• NEFU 688 Word maker! 网络流


    Word maker!

    Time Limit 5000ms

    Memory Limit 65536K

    description

    Probably, you have seen polyhedrons which have an English letter on each face of them. Little Ali has some of these polyhedrons and some words in his mind. We want to know how many of these words can be made by juxtaposing these polyhedrons. For instance, suppose that little Ali has one tetrahedron that letters B,Z,G,K are printed on its faces and one cube  which letters  O,O,O,O,O,O are printed on its faces. With this two polyhedrons little Ali can make “OK” and “GO”.
    							

    input

    First line of Input contains number of the tests.
    For each test case, first you are given an integer n, the number of polyhedrons and m, thenumber of words that  little Ali has. You can assume that 1<=n,m<=300. Then there are n string such that string i shows the letters which are printed on the faces of polyhedron i . After that you are given m words.
    							

    output

    For each test case, print number of words that little Ali can make by juxtaposing his polyhedral.
    							

    sample_input

    1
    4  3
    AAAA BBBB CCCCCC   DD
    BAD DAD  DAB 
    							

    sample_output

    2
    							
    ----------------------

    我承认我的图建麻烦了orz

    源点连word[i],word[i]连poly,poly连汇点。

    ---------------------

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <string>
    #include <vector>
    
    using namespace std;
    
    const int OO=1e9;//无穷大
    const int maxm=171111;//边的最大数量,为原图的两倍
    const int maxn=999;//点的最大数量
    
    int node,src,dest,edge;//node节点数,src源点,dest汇点,edge边数
    int head[maxn],work[maxn],dis[maxn],q[maxn];//head链表头,work临时表头,dis计算距离
    
    struct edgenode{
        int to;//边的指向
        int flow;//边的容量
        int next;//链表的下一条边
    }edges[maxm];
    
    //初始化链表及图的信息
    void prepare(int _node,int _src,int _dest)
    {
        node=_node;
        src=_src;
        dest=_dest;
        for (int i=0;i<node;i++) head[i]=-1;
        edge=0;
    }
    
    //添加一条从u到v容量为c的边
    void addedge(int u,int v,int c)
    {
        edges[edge].flow=c;edges[edge].to=v;edges[edge].next=head[u];head[u]=edge++;
        edges[edge].flow=0;edges[edge].to=u;edges[edge].next=head[v];head[v]=edge++;
    }
    
    //广搜计算出每个点与源点的最短距离,如果不能到达汇点说明算法结束
    bool Dinic_bfs()
    {
        int u,v,r=0;
        for (int i=0;i<node;i++) dis[i]=-1;
        q[r++]=src;
        dis[src]=0;
        for (int l=0;l<r;l++)
        {
            u=q[l];
            for (int i=head[u];i!=-1;i=edges[i].next)
            {
                v=edges[i].to;
                if (edges[i].flow&&dis[v]<0)
                {//这条边必须要有剩余流量
                    q[r++]=v;
                    dis[v]=dis[u]+1;
                    if (v==dest) return true;
                }
            }
        }
        return false;
    }
    
    //寻找可行流的增广路算法,按节点的距离来找,加快速度
    int Dinic_dfs(int u,int exp)
    {
        int v,tmp;
        if (u==dest) return exp;
        //work是临时链表头,这里用 i引用它,这样寻找过的边不再寻找
        for (int &i=work[u];i!=-1;i=edges[i].next)
        {
            v=edges[i].to;
            if (edges[i].flow&&dis[v]==dis[u]+1&&(tmp=Dinic_dfs(v,min(exp,edges[i].flow)))>0)
            {
                edges[i].flow-=tmp;
                edges[i^1].flow+=tmp;
                //正反向边容量改变
                return tmp;
            }
        }
        return 0;
    }
    
    //求最大流直到没有可行流
    int Dinic_flow()
    {
        int ret=0,tmp;
        while (Dinic_bfs())
        {
            for (int i=0;i<node;i++) work[i]=head[i];
            while ( tmp=Dinic_dfs(src,OO) ) ret+=tmp;
        }
        return ret;
    }
    
    vector<string>poly;
    vector<string>words;
    
    int ans;
    
    int main()
    {
        int T;
        int n,m;
        char templar[1111];
        scanf("%d",&T);
        while (T--)
        {
            poly.clear();
            words.clear();
            ans=0;
            scanf("%d%d",&n,&m);
            for (int i=1;i<=n;i++)
            {
                scanf("%s",templar);
                poly.push_back(templar);
            }
            for (int i=1;i<=m;i++)
            {
                scanf("%s",templar);
                words.push_back(templar);
            }
            for (int i=0;i<words.size();i++)
            {
                prepare(words[i].length()+n+2,0,words[i].length()+n+1);
                for (int j=0;j<words[i].length();j++)
                {
                    addedge(src,j+1,1);
                    for (int k=0;k<poly.size();k++)
                    {
                        if (poly[k].find(words[i][j])!=string::npos)
                        {
                            addedge(j+1,k+1+words[i].length(),1);
                        }
                    }
                }
                for (int k=0;k<poly.size();k++)
                {
                    addedge(k+1+words[i].length(),dest,1);
                }
                if (Dinic_flow()==words[i].length()) ans++;
            }
            printf("%d\n",ans);
        }
        return 0;
    }
    






  • 相关阅读:
    Service Mesh 在百度网盘数万后端的落地实践
    垃圾回收GC3种算法的衍生品 增量回收:预测和控制GC所产生的中断时间
    cv_list
    段式内存管理
    页式内存管理
    基本内存管理
    内存抖动
    内存管理 垃圾回收 C语言内存分配 垃圾回收3大算法 引用计数3个缺点
    DEDECMS后台传附件图片出现Upload filetype not allow解决办法
    浅谈dedecms模板引擎工作原理及自定义标签
  • 原文地址:https://www.cnblogs.com/cyendra/p/3226328.html
Copyright © 2020-2023  润新知