POJ 3281 Dining

来源:互联网 发布:后缀有.js 编辑:程序博客网 时间:2024/05/17 22:17

对每头牛进行一次拆点,为什么要进行拆点呢,因为每头牛最多对应一种饮料和食物,这样拆点后每一次进行增广时,牛与其对应点间的的前向弧就被增广掉了,不会出现多对应的情况。

#include <iostream>#include <cstdio>#include <cstring>#include <cmath>#include <vector>#include <algorithm>#include <queue>#include <set>using namespace std;const int INF=0x3f3f3f3f;const int MAXN=2000;const int MAXM=10005;int n,u,v;struct Edge{    int to,next,flow;}edge[MAXM];int head[MAXN],tot;void add(int u,int v,int w){    edge[tot].to=v;    edge[tot].flow=w;    edge[tot].next=head[u];    head[u]=tot++;    edge[tot].to=u;    edge[tot].flow=0;    edge[tot].next=head[v];    head[v]=tot++;}int dep[MAXN];bool bfs(int s,int t){    int u;    memset(dep,-1,sizeof(dep));    queue <int> q;    q.push(s);    dep[s]=0;    while(!q.empty())    {        u=q.front();        q.pop();        for(int i=head[u];~i;i=edge[i].next)        {            int v=edge[i].to;            if(dep[v]==-1&&edge[i].flow>0)            {                dep[v]=dep[u]+1;                if(v==t)return true;                q.push(v);            }        }    }    return false;}int dfs(int s,int t,int x){    if(s==t)return x;int ans=x;    for(int i=head[s];~i;i=edge[i].next)    {        int v=edge[i].to;        if(dep[v]==dep[s]+1&&edge[i].flow>0)        {            int minn=dfs(v,t,min(x,edge[i].flow));            edge[i].flow-=minn;            edge[i^1].flow+=minn;            x-=minn;        }    }    return ans-x;}int dinic(){    int ans=0;    while(bfs(1,n))ans+=dfs(1,n,INF);    return ans;}int main(){    //freopen("in.txt","r",stdin);    int a,b,c,x,y;    while(scanf("%d%d%d",&a,&b,&c)==3)    {        memset(head,-1,sizeof(head));        tot=0;n=2*a+b+c+2;        for(int i=0;i<a;++i)        {            scanf("%d%d",&x,&y);            for(int j=0;j<x;++j)            {                scanf("%d",&u);                //add(1,u+2*a+1,1);                add(u+2*a+1,2+i,1);            }            for(int j=0;j<y;++j)            {                scanf("%d",&v);                //add(2*a+b+1+v,n,1);                add(i+2+a,2*a+b+1+v,1);            }            add(i+2,i+2+a,1);        }        for(int i=0;i<b;++i)add(1,2*a+2+i,1);        for(int i=0;i<c;++i)add(2*a+b+2+i,n,1);        printf("%d\n",dinic());    }    return 0;}
0 0
原创粉丝点击