POJ3281 Dining【网络流】

来源:互联网 发布:ubuntu查看mysql路径 编辑:程序博客网 时间:2024/05/16 17:13

题意:一头牛喜欢某种食物或饮料,问最多让几头牛同时拥有食物和饮料


思路:把牛拆成两个点, 保证每头牛只算一次,起点 → 食物 牛入点 牛出点 饮料 汇点,求最大流。用一下Dinic的模板.

不知道下面的普通的最大流为什么过不了,有人知道吗,请留言


#include<stdio.h>#include<iostream>#include<string.h>#include<string>#include<stdlib.h>#include<math.h>#include<vector>#include<list>#include<map>#include<set>#include<stack>#include<queue>#include<algorithm>#include<numeric>#include<functional>using namespace std;typedef long long ll;typedef pair<int,int> pii;const int maxn = 505; struct edge {int to,cf,rev;};vector<edge> G[maxn];int lev[maxn],iter[maxn];void init(int x){for(int i = 0; i <= x; i++)G[i].clear();}void add(int from, int to, int cap){G[from].push_back((edge){to,cap,G[to].size()});G[to].push_back((edge){from,0,G[from].size()-1});}void bfs(int s){memset(lev,-1,sizeof lev);queue<int> q;lev[s] = 0;q.push(s);while(!q.empty()){int v = q.front();q.pop();for(int i = 0; i < G[v].size(); i++){edge &e = G[v][i];if(e.cf > 0 && lev[e.to] < 0){lev[e.to] = lev[v] + 1;q.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.cf > 0 && lev[v] < lev[e.to]){int d = dfs(e.to, t, min(f,e.cf));if(d > 0){e.cf -= d;G[e.to][e.rev].cf += d;return d;}}}return 0;}int maxflow(int s,int t){int flow = 0;while(1){bfs(s);if(lev[t] < 0) return flow;memset(iter,0,sizeof iter);int f;while((f = dfs(s,t,0x3f3f3f3f)) > 0)flow += f;}}int main(void){int n,d,f;while(scanf("%d%d%d",&n,&f,&d)!=EOF){init(2*n+f+d+5);for(int i = 0; i < n; i++){int a,b,k;scanf("%d%d",&a,&b);while(a--){scanf("%d",&k);add(k,f+1+2*i,1);}while(b--){scanf("%d",&k);add(f+1+2*i+1,f+2*n+k,1);}}for(int i = 1; i <= f; i++)add(0,i,1);for(int i = 0; i < n; i++)add(f+1+2*i,f+1+2*i+1,1);for(int i = 1; i <= d; i++)add(f+2*n+i,f+2*n+d+1,1);int ans = maxflow(0,f+2*n+d+1);printf("%d\n",ans);}return 0;}

#include<stdio.h>#include<iostream>#include<string.h>#include<string>#include<stdlib.h>#include<math.h>#include<vector>#include<list>#include<map>#include<set>#include<stack>#include<queue>#include<algorithm>#include<numeric>#include<functional>using namespace std;typedef long long ll;typedef pair<int,int> pii;const int maxn = 505; int cf[maxn][maxn],fa[maxn],liu[maxn];  //cf残流 int vis[maxn];vector<int> v[maxn];void init(int x){memset(cf,0,sizeof cf);for(int i = 0; i <= x; i++)v[i].clear();}int fid(int st,int en){queue<int> q;memset(liu,0,sizeof liu);memset(vis,0,sizeof vis);memset(fa,-1,sizeof fa);liu[st] = 0x3f3f3f3f;q.push(st);vis[st] = 1;while(!q.empty()){int now = q.front();q.pop();if(now == en)return liu[en];for(int i = 0; i < v[now].size(); i++){int temp = v[now][i];if(cf[now][temp] > 0 && !vis[temp]){vis[temp] = 1;liu[temp] = min(cf[now][temp], liu[now]);fa[temp] = now;q.push(temp);}}}return liu[en];}void up(int st,int en){int temp = en,s = liu[en];while(temp != st){cf[ fa[temp] ][temp] -= s;cf[temp][ fa[temp] ] += s;temp = fa[temp];}}void add(int a,int b,int c){cf[a][b] = c;}int main(void){int n,d,f;while(scanf("%d%d%d",&n,&f,&d)!=EOF){init(2*n+f+d+5);for(int i = 0; i < n; i++){int a,b,k;scanf("%d%d",&a,&b);while(a--){scanf("%d",&k);add(k,f+1+2*i,1);}while(b--){scanf("%d",&k);add(f+1+2*i+1,f+2*n+k,1);}}for(int i = 1; i <= f; i++)add(0,i,1);for(int i = 0; i < n; i++)add(f+1+2*i,f+1+2*i+1,1);for(int i = 1; i <= d; i++)add(f+2*n+i,f+2*n+d+1,1);int ans = 0,num;while( (num = fid(0,f+2*n+d+1)) ){ans += num;up(0,f+2*n+d+1);}printf("%d\n",ans);}return 0;}