POJ 3281 网络流

来源:互联网 发布:软壳冲锋衣 知乎 编辑:程序博客网 时间:2024/05/16 12:37

题意:
这里写图片描述
这里写图片描述
思路:
网络流 重在建图…

建完了图 就一切都好说了

这道题 我的想法是 先把源点和所有的食品连上边 (容量为1)

再把食品和对应的奶牛连上边 (容量为1)

这个时候要拆点 因为每只奶牛只能才吃1种东西嘛

就把奶牛拆成两个点

两个点之间连上一条容量为1的边

把奶牛分裂的第二个点 连到对应的饮料上

最后所有饮料向汇点连一条容量为1的边就好啦

大功告成~~~

//By SiriusRen#include <queue> #include <cstdio>#include <cstring>#include <algorithm>using namespace std;#define N 100050int n,f,d,ans,xx,w[N],v[N],first[555],tot,next[N],vis[N],yy,jy;void add(int x,int y,int z){    w[tot]=z,v[tot]=y,next[tot]=first[x],first[x]=tot++;}bool tell(){    queue<int>q;    q.push(0);    memset(vis,-1,sizeof(vis));    vis[0]=0;    while(!q.empty()){        int t=q.front();q.pop();        for(int i=first[t];~i;i=next[i]){            if(w[i]&&vis[v[i]]==-1){                q.push(v[i]);                vis[v[i]]=vis[t]+1;            }        }    }    return vis[501]!=-1;}int zeng(int x,int y){    if(x==501)return y;    int r=0;    for(int i=first[x];y>r&&~i;i=next[i]){        if(w[i]&&vis[v[i]]==vis[x]+1){            int t=zeng(v[i],min(y-r,w[i]));            w[i]-=t,w[i^1]+=t,r+=t;        }    }    if(!r)vis[x]=-1;    return r;}void flow(){    while(tell())while(xx=zeng(0,0x3fffffff))ans+=xx;    printf("%d\n",ans);}int main(){    memset(first,-1,sizeof(first));    scanf("%d%d%d",&n,&f,&d);    for(int i=1;i<=f;i++)add(0,i,1),add(i,0,0);     for(int i=1;i<=n;i++){        add(100+i,200+i,1);        add(200+i,100+i,0);        scanf("%d%d",&xx,&yy);        for(int j=1;j<=xx;j++){            scanf("%d",&jy);            add(jy,100+i,1);            add(100+i,jy,0);        }        for(int j=1;j<=yy;j++){            scanf("%d",&jy);            add(200+i,300+jy,1);            add(300+jy,200+i,0);        }    }    for(int i=1;i<=d;i++)add(300+i,501,1),add(501,300+i,0);    flow();}

这里写图片描述

0 0
原创粉丝点击