poj3281--Dining(最大流(EK算法))

来源:互联网 发布:电脑保密软件 编辑:程序博客网 时间:2024/06/04 19:40

题目来源:http://poj.org/problem?id=3281

题意

给出n头牛,d杯饮料(都比我过得好。。。T^T),以及f份食物,每头牛有各自喜欢的食物和饮料,那么每头牛吃饱喝好才算可以,所以问给出的东西能令多少牛吃饱。。。(吃完就没啦。。。)

思路

或许这道题可以弄成三分图匹配(胡诌的。。)。。
但是这是一道最大流模板题,本菜采用的最糟糕的EK算法,主要的一点就是如何去构图,,,
对于样例,构建如下图:
这里写图片描述
为啥cow要到cow,为了防止cow被重复使用,用边去判断是否使用过。。

代码

#include<cmath>#include<stack>#include<queue>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int maxn=100+10;int n,f,d,s,t;int F[maxn][maxn],D[maxn][maxn];int c[maxn*5][maxn*5],vis[maxn*5],pre[maxn*5];void init(){    scanf("%d%d%d",&n,&f,&d);    memset(F,0,sizeof(F));    memset(D,0,sizeof(D));    for(int i=1; i<=n; i++)    {        int ff,dd;        scanf("%d%d",&ff,&dd);        while(ff--)        {            int x;            scanf("%d",&x);            F[i][x]=1;        }        while(dd--)        {            int y;            scanf("%d",&y);            D[i][y]=1;        }    }}bool bfs(){    memset(vis,0,sizeof(vis));    queue<int> Q;    while(!Q.empty()) Q.pop();    Q.push(s);    vis[s]=1;    while(!Q.empty())    {        int u=Q.front();        Q.pop();        for(int v=s;v<=t;v++)        {            if(!vis[v]&&c[u][v]>0)            {                pre[v]=u;                if(v==t)                    return 1;                Q.push(v);                vis[v]=1;            }        }    }    return 0;}void print_EK(){    s=0,t=f+d+2*n+1;    int maxflow=0;    while(bfs())    {        int tt=t;        while(tt!=s)        {            c[pre[tt]][tt]--;            c[tt][pre[tt]]++;            tt=pre[tt];        }        maxflow++;    }    printf("%d\n",maxflow);}void build_graph()//一共f+2*n+d+2个点,0~f+2*n+d+1{    memset(c,0,sizeof(c));    for(int i=1; i<=f; i++) //s->food        c[0][i]=1;    for(int i=f+2*n+1; i<=f+2*n+d; i++) //drink->t        c[i][f+2*n+d+1]=1;    for(int i=1; i<=n; i++)    {        for(int j=1; j<=f; j++) //food-->cow            if(F[i][j])                c[j][f+i]=1;            c[f+i][f+n+i]=1;//cow-->cow        for(int j=1; j<=d; j++) //cow-->drink            if(D[i][j])                c[f+n+i][f+2*n+j]=1;    }}int main(){    init();    build_graph();//建图。。    print_EK();    return 0;}//网络流第一道题,,,患得患失。。好菜,,,
原创粉丝点击