[kuangbin带你飞]专题十一 网络流 B POJ

来源:互联网 发布:php m常用字符串函数 编辑:程序博客网 时间:2024/06/06 12:30

题目地址:https://vjudge.net/contest/68128#problem/B

思路:拆点,将牛拆成两个点,一个与食物联通,一个与饮料联通,然后两个拆开的牛再联通,这样就可以保证符合每头牛的选择标准。使用超级源点与食物相连,超级汇点与饮料相连,每条边流量显然为1,每次有一个符合条件的选择,总流量就会+1,所以答案即为该图超级起点到超级汇点的最大流。

AC代码:

#include<iostream>#include<cstdio>#include<queue>#include<cstring>using namespace std;const int MAXN = 505;const int MAXM =1e6+10;const int INF = 0x3f3f3f3f;int head[MAXN];int tol;struct edge{    int u,v,next,cap;}edge[MAXM];void init(){    memset(head,-1,sizeof(head));    tol=0;}void addedge(int u,int v,int w){    edge[tol].u=u;    edge[tol].v=v;    edge[tol].cap=w;    edge[tol].next=head[u];    head[u]=tol++;    edge[tol].u=v;    edge[tol].v=u;    edge[tol].cap=0;    edge[tol].next=head[v];    head[v]=tol++;}int dep[MAXN];bool bfs(int s,int t){    queue<int>q;    memset(dep,-1,sizeof(dep));    dep[s]=0;    q.push(s);    while(!q.empty()){        int u=q.front();        q.pop();        for(int i=head[u];i!=-1;i=edge[i].next){            int v=edge[i].v;            if(edge[i].cap>0 && dep[v]==-1){                dep[v]=dep[u]+1;                if(v==t)                    return true;                q.push(v);            }        }    }    return false;}int dfs(int a,int b,int s,int t){    int r=0;    if(a==t)        return b;    for(int i=head[a];i!=-1;i=edge[i].next){        int u=edge[i].v;        if(edge[i].cap>0 && dep[u]==dep[a]+1){            int x=min(edge[i].cap,b-r);            x=dfs(u,x,s,t);            edge[i].cap-=x;            edge[i^1].cap+=x;            r+=x;        }    }    if(!r)        dep[a]=-1;    return r;}int dinic(int s,int t){    int total=0;    int temp;    while(bfs(s,t)){        if(temp=dfs(s,INF,s,t)){            total+=temp;        }    }    return total;}int n,f,d;struct pos{    int f,d;    int food[105];    int drink[105];}cow[105];int main(){    init();    scanf("%d%d%d",&n,&f,&d);    for(int i=1;i<=n;i++){        scanf("%d%d",&cow[i].f,&cow[i].d);        for(int j=1;j<=cow[i].f;j++){            scanf("%d",&cow[i].food[j]);        }        for(int j=1;j<=cow[i].d;j++){            scanf("%d",&cow[i].drink[j]);        }    }    for(int i=1;i<=f;i++){        addedge(0,2*n+i,1);    }    for(int i=1;i<=d;i++){        addedge(2*n+f+i,2*n+f+d+1,1);    }    for(int i=1;i<=n;i++){        addedge(i,i+n,1);        for(int j=1;j<=cow[i].f;j++){            addedge(cow[i].food[j]+2*n,i,1);        }         for(int j=1;j<=cow[i].d;j++){            addedge(i+n,cow[i].drink[j]+2*n+f,1);        }    }    int ans=dinic(0,2*n+f+d+1);    printf("%d\n",ans);}
0 0
原创粉丝点击