POJ3281 Dining

来源:互联网 发布:数据库原理与应用 pdf 编辑:程序博客网 时间:2024/05/17 22:58
 经典的网络流建模题,开始其实就想到food连牛连drink,但没想到怎么控制一头牛只吃一份food和一份drink,后来换了一种想法是一头牛连一头左牛,一头右牛,分别连饮料,食物,这样可以做到把一头牛吃的食物和drink分开来,但还是不能解决一头牛各吃一份,最后想起开始的思路,发现一头牛可以拆成左牛右牛控制流量啊,bingo。
#include <cstdio>#include <cstring>#include <algorithm>#include <iostream>#include <string>#include <vector>#include <stack>#include <bitset>#include <cstdlib>#include <cmath>#include <set>#include <list>#include <deque>#include <map>#include <queue>using namespace std;typedef long long ll;#define inf 0x3f3f3f3f#define maxn 1000struct edge {int to,cap,rev;};int level [maxn];vector <edge> G[maxn];int iter[maxn];void add_edge (int from,int to,int cap){    G[from].push_back ((edge){to,cap,static_cast<int>(G[to].size())});    G[to].push_back ((edge){from,0,static_cast<int>(G[from].size()-1)});}void bfs (int s){    memset (level,-1,sizeof (level));    queue<int> que;    level[s] = 0;    que.push (s);    while (!que.empty()){        int v=que.front ();        que.pop ();        int i;        for (i=0;i<G[v].size();i++){            edge &e = G[v][i];            if (e.cap>0 && level[e.to]<0){                level[e.to]=level[v]+1;                que.push(e.to);            }        }    }}int dfs (int v,int t,int f){    if (v==t) return f;    for (int &i=iter[v];i<G[v].size();i++){        edge &e =G[v][i];        if (e.cap>0 && level[v]<level[e.to]){            int d=dfs(e.to,t,min(f,e.cap));            if(d>0){                e.cap-=d;                G[e.to][e.rev].cap+=d;                return d;            }        }    }    return 0;}int maxflow (int s,int t){    int flow = 0;    for (;;){        bfs (s);        if (level[t]<0) return flow;        memset (iter, 0,sizeof(iter));        int f;        while ((f=dfs(s,t,inf))>0){            flow += f;        }    }}int main (){    int n,f,d;    int i;    while (scanf ("%d %d %d",&n,&f,&d)!=EOF){        int food = 1;        int cow = f+1;        int cow2 = n+d+f+1;        int t = cow2+n;        int dnk = n+f+1;        for (i=1;i<=n;i++){            int F,D;            add_edge(cow+i-1, cow2+i-1, 1);            scanf ("%d %d",&F,&D);            for (int j=1;j<=F;j++){                int v;                scanf ("%d",&v);                add_edge (v,cow+i-1,1);            }            for (int j=1;j<=D;j++){                int v;                scanf("%d",&v);                add_edge (cow2+i-1,dnk+v-1,1);            }        }        for (i=1;i<=f;i++){            add_edge (0,food+i-1,1);        }        for (i=1;i<=d;i++){            add_edge (dnk+i-1,t,1);        }        printf("%d\n", maxflow(0,t));    }    return 0;}