BZOJ 1711 网络流

来源:互联网 发布:淘宝雪肌精 编辑:程序博客网 时间:2024/05/20 02:24

将每个牛拆成两个牛,连一条流量为1的边,就能保证每个牛只选择一次,从源点向每一个饮料连一条容量为1的边,每个食物向汇点连一条容量为1的边,然后一只牛就表示为它喝的饮料向他自己连一条边,他自己再向吃的食物连一条边,跑一个最大流

#include<cstdio>#include<cstdlib>#include<ctime>#include<cmath>#include<iostream>#include<iomanip>#include<cstring>#include<string>#include<algorithm>using namespace std;struct bian{    int l,r,f;}a[1000000];int fir[1000000];int nex[1000000];int d[1000];int tot=1;int s,t;void add_edge(int l,int r,int f){    a[++tot].l=l;    a[tot].r=r;    a[tot].f=f;    nex[tot]=fir[l];    fir[l]=tot;}bool bfs(){    static int dui[1000];    int top=1,my_final=2;    memset(d,-1,sizeof(d));    dui[top]=s;    d[s]=0;    while(top<my_final)    {        int u=dui[top];        for(int o=fir[u];o!=0;o=nex[o])        {            if(d[a[o].r]!=-1 || !a[o].f) continue;            d[a[o].r]=d[u]+1;            dui[my_final++]=a[o].r;            if(a[o].r==t) return true;        }        top++;    }    return false;}int dinic(int u,int flow){    int left=flow;    if(u==t) return flow;    for(int o=fir[u];o!=0 && left;o=nex[o])    {        if(d[a[o].r]==d[u]+1 && a[o].f)        {            int temp=dinic(a[o].r,min(flow,a[o].f));            if(temp==0) d[a[o].r]=-1;            left-=temp;            a[o].f-=temp;            a[o^1].f+=temp;        }    }    return flow-left;}int main(){    s=0;    int n,f,d;    scanf("%d%d%d",&n,&f,&d);    t=999;    for(int i=1;i<=f;i++)    {        add_edge(s,i+2*n,1);        add_edge(i+2*n,s,0);    }    for(int i=1;i<=d;i++)    {        add_edge(2*n+f+i,t,1);        add_edge(t,2*n+f+i,0);    }    for(int i=1;i<=n;i++)    {        add_edge(i,n+i,1);        add_edge(n+i,i,0);    }    for(int i=1;i<=n;i++)    {        int x,y;        scanf("%d%d",&x,&y);        for(int j=1;j<=x;j++)        {            int mid;            scanf("%d",&mid);            add_edge(mid+2*n,i,1);            add_edge(i,mid+2*n,0);        }        for(int j=1;j<=y;j++)        {            int mid;            scanf("%d",&mid);            add_edge(n+i,2*n+f+mid,1);            add_edge(2*n+f+mid,n+i,0);        }    }    int ans=0;    while(bfs()) ans+=dinic(s,20000000);    cout<<ans;    return 0;}
1 1
原创粉丝点击