B - Dining POJ - 3281 -网络流拆点模板

  • B - Dining

  •  POJ - 3281 
  • 题意:一些牛,每只牛有 一些  想吃的food and milk,然后问最大能够满足多少只牛。
  • 满足是指的这头牛即能吃到他喜欢吃的又能喝到他喜欢喝的
  • 思路:最大流,关键建出图来,源点汇点肯定是要有的,然后中间呢因为满足一头牛的需求是有一个food and milk
  • 所以为了保证结果最大只需要经过每个牛一次就行了,这里就需要把牛copy一遍中间自己到自己连一条边权为1的边
  • 而且 为了 达到 "满足“这个效果 很明显不能把food and milk 放在一遍 ,需要用牛在中间把他们隔开。
  • 整体上一条流量是这样的 :源点——food——牛——牛——milk——汇点

  • #include<stdio.h>
    #include<cstring>
    #include<queue>
    using namespace std;
    #define maxn 10005
    #define inf 0x3f3f3f3f
    struct node
    {
        int to,v,w;
    } edge[maxn*20];
    int head[maxn],totlen,f;
    int level[maxn],s,t,n,d;
    int sum,orz,QYN,cnt=-1;
    void add(int x,int y,int z)
    {
        edge[++cnt].to=head[x];
        head[x]=cnt;
        edge[cnt].v=y;
        edge[cnt].w=z;
        edge[++cnt].to=head[y];
        head[y]=cnt;
        edge[cnt].v=x;
        edge[cnt].w=0;
    }
    bool dinic_bfs()
    {
        memset(level,0,sizeof(level));
        queue<int>que;
        que.push(0);
        level[0]=1;
        while(!que.empty())
        {
            int u=que.front();
            que.pop();
            for(int i=head[u]; i!=-1; i=edge[i].to)
            {
                int v=edge[i].v;
                if(!level[v]&&edge[i].w>0)
                {
                    level[v]=level[u]+1;
                    que.push(v);
                }
            }
        }
        return level[sum]!=0;
    }
    int dinic_dfs(int u,int cpflow)
    {
        if(u==sum)return cpflow;
        int addflow=0;
        for(int i=head[u]; i!=-1&&addflow<cpflow; i=edge[i].to)
        {
            int v=edge[i].v;
            if(level[u]+1==level[v]&&edge[i].w>0)
            {
                int temp=dinic_dfs(v,min(cpflow-addflow,edge[i].w));
                edge[i].w-=temp;
                edge[i^1].w+=temp;
                addflow+=temp;
            }
        }
        return addflow;
    }
    void  dinic()
    {
        int maxflow=0;
        while(dinic_bfs())
            maxflow+=dinic_dfs(0,sum);
        printf("%d\n",maxflow);
    }
    int main()
    {
        scanf("%d%d%d",&n,&f,&d);
        sum=n+f+d+n+1;
        int s1=n+f+n,s2=n+f,s3=f;
        memset(head,-1,sizeof(head));
        for(int i=1; i<=f; i++)
            add(0,i,1);
        for(int i=1; i<=n; i++)
            add(i+s3,i+s2,1);
        for(int i=1; i<=d; i++)
            add(s1+i,sum,1);
        for(int i=1; i<=n; i++)
        {
            scanf("%d%d",&f,&d);
            while(f--)
            {
                scanf("%d",&orz);
                add(orz,s3+i,1);
            }
            while(d--)
            {
                scanf("%d",&orz);
                add(s2+i,s1+orz,1);
            }
        }
        dinic();
        return 0;
    }
    

猜你喜欢

转载自blog.csdn.net/BePosit/article/details/83863473