poj 1149 PIGS(最大流经典构图)
题目描述:
迈克在一个养猪场工作,养猪场里有M 个猪圈,每个猪圈都上了锁。由于迈克没有钥匙,所
以他不能打开任何一个猪圈。要买猪的顾客一个接一个来到养猪场,每个顾客有一些猪圈的钥匙,
而且他们要买一定数量的猪。某一天,所有要到养猪场买猪的顾客,他们的信息是要提前让迈克
知道的。这些信息包括:顾客所拥有的钥匙(详细到有几个猪圈的钥匙、有哪几个猪圈的钥匙)、
要购买的数量。这样对迈克很有好处,他可以安排销售计划以便卖出的猪的数目最大。
更详细的销售过程:当每个顾客到来时,他将那些他拥有钥匙的猪圈全部打开;迈克从这些
猪圈中挑出一些猪卖给他们;如果迈克愿意,迈克可以重新分配这些被打开的猪圈中的猪;当顾
客离开时,猪圈再次被锁上。注意:猪圈可容纳的猪的数量没有限制。
编写程序,计算迈克这一天能卖出猪的最大数目。
构图:源点连接每一个猪圈的第一个打开的顾客,容量为该猪圈的猪数;
下一次的顾客连接上一次的顾客,容量为INF;
接着每个顾客连接到汇点,容量为该顾客所需猪数。
这样构图是因为每一次打开猪圈猪可以重新分配,第一次打开猪圈的顾客可以把猪都流到他这里,再分流到下一个顾客或者汇点,这样就可以利用最大流来得到最优解。
1 /* 2 *Author: Zhaofa Fang 3 *Created time: 2013-07-17-10.23 4 *Language: C++ 5 */ 6 #include <cstdio> 7 #include <cstdlib> 8 #include <sstream> 9 #include <iostream> 10 #include <cmath> 11 #include <cstring> 12 #include <algorithm> 13 #include <string> 14 #include <utility> 15 #include <vector> 16 #include <queue> 17 #include <map> 18 #include <set> 19 using namespace std; 20 21 typedef long long ll; 22 #define DEBUG(x) cout<< #x << ':' << x << endl 23 #define FOR(i,s,t) for(int i = (s);i <= (t);i++) 24 #define FORD(i,s,t) for(int i = (s);i >= (t);i--) 25 #define REP(i,n) for(int i=0;i<(n);i++) 26 #define REPD(i,n) for(int i=(n-1);i>=0;i--) 27 #define PII pair<int,int> 28 #define PB push_back 29 #define MP make_pair 30 #define ft first 31 #define sd second 32 #define lowbit(x) (x&(-x)) 33 #define INF (1<<30) 34 #define eps 1e-8 35 36 const int maxn = 505; 37 const int maxm = 400011; 38 39 struct Edge{ 40 int v,cap,flow,next; 41 }edge[maxm]; 42 int eh[maxn],tot; 43 bool vist[maxn]; 44 int d[maxn]; 45 46 void init(){ 47 tot = 0; 48 memset(eh,-1,sizeof(eh)); 49 } 50 void addedge(int u,int v,int c){ 51 Edge e = {v,c,0,eh[u]}; 52 edge[tot] = e; 53 eh[u] = tot ++; 54 } 55 void add(int u,int v,int c){ 56 addedge(u,v,c); 57 addedge(v,u,0); 58 } 59 bool BFS(int s,int t){ 60 memset(vist,0,sizeof(vist)); 61 queue<int>Q; 62 Q.push(s); 63 d[s] = 0; 64 vist[s] = 1; 65 while(!Q.empty()){ 66 int u = Q.front(); 67 Q.pop(); 68 for(int i=eh[u];i!=-1;i=edge[i].next){ 69 int v = edge[i].v; 70 if(!vist[v] && edge[i].cap > edge[i].flow){ 71 vist[v] = 1; 72 d[v] = d[u] + 1; 73 if(v == t)return true; 74 Q.push(v); 75 } 76 } 77 } 78 return false; 79 } 80 int DFS(int u,int t,int avi){ 81 if(u == t || avi == 0)return avi; 82 int flow = 0 , f; 83 for(int i=eh[u];i!=-1;i=edge[i].next){ 84 int v = edge[i].v; 85 if(d[v] == d[u] + 1 && (f=DFS(v,t,min(avi,edge[i].cap-edge[i].flow)))>0){ 86 edge[i].flow += f; 87 edge[i^1].flow -= f; 88 flow += f; 89 avi -= f; 90 if(avi == 0)break; 91 } 92 } 93 return flow; 94 } 95 int maxFlow(int s,int t){ 96 int flow = 0; 97 while(BFS(s,t))flow += DFS(s,t,INF); 98 return flow; 99 } 100 int pig[maxn],last[maxn]; 101 int main(){ 102 //freopen("in","r",stdin); 103 //freopen("out","w",stdout); 104 int n,m; 105 while(~scanf("%d%d",&m,&n)){ 106 int A,B,u,v; 107 init(); 108 FOR(i,1,m)scanf("%d",&pig[i]); 109 memset(last,0,sizeof(last)); 110 FOR(i,1,n){ 111 scanf("%d",&A); 112 REP(j,A){ 113 scanf("%d",&u); 114 if(!last[u])add(0,i,pig[u]); 115 else add(last[u],i,INF); 116 last[u] = i; 117 } 118 scanf("%d",&B); 119 add(i,n+1,B); 120 } 121 printf("%d\n",maxFlow(0,n+1)); 122 } 123 return 0; 124 }
by Farmer