POJ 3281 Dining(最大流)
http://poj.org/problem?id=3281
题意:
有n头牛,F种食物和D种饮料,每头牛都有自己喜欢的食物和饮料,每种食物和饮料只能给一头牛,每头牛需要1食物和1饮料。问最多能满足几头牛的需求。
思路:
1 #include<iostream> 2 #include<algorithm> 3 #include<cstring> 4 #include<cstdio> 5 #include<sstream> 6 #include<vector> 7 #include<stack> 8 #include<queue> 9 #include<cmath> 10 #include<map> 11 #include<set> 12 using namespace std; 13 typedef long long ll; 14 typedef long long ull; 15 typedef pair<int,int> pll; 16 const int INF = 0x3f3f3f3f; 17 const int maxn = 1000 + 5; 18 19 struct Edge 20 { 21 int from,to,cap,flow; 22 Edge(int u,int v,int w,int f):from(u),to(v),cap(w),flow(f){} 23 }; 24 25 struct Dinic 26 { 27 int n,m,s,t; 28 vector<Edge> edges; 29 vector<int> G[maxn]; 30 bool vis[maxn]; 31 int cur[maxn]; 32 int d[maxn]; 33 34 void init(int n) 35 { 36 this->n=n; 37 for(int i=0;i<n;++i) G[i].clear(); 38 edges.clear(); 39 } 40 41 void AddEdge(int from,int to,int cap) 42 { 43 edges.push_back( Edge(from,to,cap,0) ); 44 edges.push_back( Edge(to,from,0,0) ); 45 m=edges.size(); 46 G[from].push_back(m-2); 47 G[to].push_back(m-1); 48 } 49 50 bool BFS() 51 { 52 queue<int> Q; 53 memset(vis,0,sizeof(vis)); 54 vis[s]=true; 55 d[s]=0; 56 Q.push(s); 57 while(!Q.empty()) 58 { 59 int x=Q.front(); Q.pop(); 60 for(int i=0;i<G[x].size();++i) 61 { 62 Edge& e=edges[G[x][i]]; 63 if(!vis[e.to] && e.cap>e.flow) 64 { 65 vis[e.to]=true; 66 d[e.to]=d[x]+1; 67 Q.push(e.to); 68 } 69 } 70 } 71 return vis[t]; 72 } 73 74 int DFS(int x,int a) 75 { 76 if(x==t || a==0) return a; 77 int flow=0, f; 78 for(int &i=cur[x];i<G[x].size();++i) 79 { 80 Edge &e=edges[G[x][i]]; 81 if(d[e.to]==d[x]+1 && (f=DFS(e.to,min(a,e.cap-e.flow) ) )>0) 82 { 83 e.flow +=f; 84 edges[G[x][i]^1].flow -=f; 85 flow +=f; 86 a -=f; 87 if(a==0) break; 88 } 89 } 90 return flow; 91 } 92 93 int Maxflow(int s,int t) 94 { 95 this->s=s; this->t=t; 96 int flow=0; 97 while(BFS()) 98 { 99 memset(cur,0,sizeof(cur)); 100 flow +=DFS(s,INF); 101 } 102 return flow; 103 } 104 }DC; 105 106 int n,F,D; 107 108 int main() 109 { 110 //freopen("in.txt","r",stdin); 111 while(~scanf("%d%d%d",&n,&F,&D)) 112 { 113 int src=0, dst=F+D+2*n+1; 114 DC.init(dst+1); 115 116 for(int i=1;i<=F;i++) DC.AddEdge(src,i,1); 117 for(int i=1;i<=D;i++) DC.AddEdge(F+i,dst,1); 118 119 for(int i=1;i<=n;i++) 120 { 121 DC.AddEdge(F+D+i,F+D+n+i,1); 122 int num1,num2; 123 124 scanf("%d%d",&num1,&num2); 125 while(num1--) 126 { 127 int x; 128 scanf("%d",&x); 129 DC.AddEdge(x,F+D+i,1); 130 } 131 while(num2--) 132 { 133 int x; 134 scanf("%d",&x); 135 DC.AddEdge(F+D+n+i,F+x,1); 136 } 137 } 138 printf("%d\n",DC.Maxflow(src,dst)); 139 } 140 return 0; 141 }