POJ1149 网络流最大流
PIGS
Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 12372 | Accepted: 5476 |
Description
Mirko works on a pig farm that consists of M locked pig-houses and Mirko can't unlock any pighouse because he doesn't have the keys. Customers come to the farm one after another. Each of them has keys to some pig-houses and wants to buy a certain number of pigs. All data concerning customers planning to visit the farm on that particular day are available to Mirko early in the morning so that he can make a sales-plan in order to maximize the number of pigs sold. More precisely, the procedure is as following: the customer arrives, opens all pig-houses to which he has the key, Mirko sells a certain number of pigs from all the unlocked pig-houses to him, and, if Mirko wants, he can redistribute the remaining pigs across the unlocked pig-houses.
An unlimited number of pigs can be placed in every pig-house. Write a program that will find the maximum number of pigs that he can sell on that day.
An unlimited number of pigs can be placed in every pig-house. Write a program that will find the maximum number of pigs that he can sell on that day.
Input
The first line of input contains two integers M and N, 1 <= M <= 1000, 1 <= N <= 100, number of pighouses and number of customers. Pig houses are numbered from 1 to M and customers are numbered from 1 to N. The next line contains M integeres, for each pig-house initial number of pigs. The number of pigs in each pig-house is greater or equal to 0 and less or equal to 1000. The next N lines contains records about the customers in the following form ( record about the i-th customer is written in the (i+2)-th line): A K1 K2 ... KA B It means that this customer has key to the pig-houses marked with the numbers K1, K2, ..., KA (sorted nondecreasingly ) and that he wants to buy B pigs. Numbers A and B can be equal to 0.
Output
The first and only line of the output should contain the number of sold pigs.
Sample Input
3 3
3 1 10
2 1 2 2
2 1 3 3
1 2 6
Sample Output
7
题意:M个猪圈,N个顾客,每个顾客有一些的猪圈的钥匙,只能购买这些有钥匙的猪圈里的猪,而且要买一定数量的猪,每个猪圈有已知数量的猪,
但是猪圈可以重新打开,将猪的个数,重新分配,以达到卖出的猪的数量最多。
思路:刚学网络流,表示很菜很菜很菜~~
①构造网络,将顾客看成源点和汇点以外的结点,并设另外两个节点:源点和汇点。
②源点和每个猪圈的第一个顾客连边,边的权是开始时候猪圈中猪的数量。
③ 若源点和某个节点之间有重边,则将权合并
④顾客j紧跟顾客i之后打开某个猪圈,则<i.j>的权是正无穷。
⑤每个顾客和会点之间连边,边的权值是顾客所希望购买的猪的数量。
例如:样例中的就可以建立如图:
其中inf是正无穷~~
View Code
1 #include <cmath> 2 #include <cstdio> 3 #include <cstring> 4 #include <iostream> 5 #include <algorithm> 6 using namespace std; 7 #define INF 300000000 8 #define M 1002 9 #define N 102 10 int s,t; 11 int cus[N][N]; 12 int flow[N][N]; 13 int i,j; 14 void ford() 15 { 16 int prev[N]; 17 int minflow[N]; 18 int queue[N]; 19 int qs,qe,v,p; 20 for(i=0;i<N;i++) 21 for(j=0;j<N;j++) 22 flow[i][j]=0; 23 minflow[0]=INF; 24 while(1) 25 { 26 for(i=0;i<N;i++) 27 prev[i]=-2; 28 prev[0]=-1; 29 qs=0; 30 queue[qs]=0; 31 qe=1; 32 while(qs<qe&&prev[t]==-2) 33 { 34 v=queue[qs++]; 35 for(i=0;i<t+1;i++) 36 { 37 if(prev[i]==-2&&(p=cus[v][i]-flow[v][i])) 38 { 39 prev[i]=v; queue[qe++]=i; 40 minflow[i]=(minflow[v]<p)?minflow[v]:p; 41 } 42 } 43 } 44 if(prev[t]==-2) break; 45 for(i=prev[t],j=t;i!=-1;j=i,i=prev[i]) 46 { 47 flow[i][j]=flow[i][j]+minflow[t]; 48 flow[j][i]=-flow[i][j]; 49 } 50 } 51 for(i=0,p=0;i<t;i++) 52 p=p+flow[i][t]; 53 printf("%d\n",p); 54 } 55 int main() 56 { 57 int m,n; 58 int num,k; 59 int house[M],last[M]; 60 while(scanf("%d %d",&m,&n)!=EOF) 61 { 62 memset(last,0,sizeof(last)); 63 memset(cus,0,sizeof(cus)); 64 s=0;t=n+1; 65 for(i=1;i<=m;i++) 66 scanf("%d",&house[i]); 67 for(i=1;i<=n;i++) 68 { 69 scanf("%d",&num); 70 for(j=0;j<num;j++) 71 { 72 scanf("%d",&k); 73 if(last[k]==0) 74 cus[s][i]=cus[s][i]+house[k]; 75 else 76 cus[last[k]][i]=INF; 77 last[k]=i; 78 } 79 scanf("%d",&cus[i][t]); 80 } 81 ford(); 82 } 83 }
poj1273 一般增光路算法(残余网络),find_augment_path求增光路,并通过augment_flow计算可改进量,然后调用update_flow更新网络流,直到不存在增光路为止。
View Code
1 #include <stdio.h> 2 #include <string.h> 3 #include <iostream> 4 using namespace std; 5 #define M 210 6 struct Matix{ 7 int c,f; 8 }edge[M][M]; 9 int n,m; 10 int s,t; 11 int resi[M][M]; 12 int qu[M*M],qs,qe; 13 int pre[M]; 14 int vis[M]; 15 int maxflow,min_augment; 16 void find_augment_path(){ 17 int i,v; 18 memset(vis,0,sizeof(vis)); 19 qs=0;qu[qs]=s; 20 pre[s]=s;vis[s]=1;qe=1; 21 memset(resi,0,sizeof(resi)); 22 memset(pre,0,sizeof(pre)); 23 while(qs<qe&&pre[t]==0){ 24 v=qu[qs++]; 25 for(i=1;i<=n;i++){ 26 if(vis[i]==0){ 27 if(edge[v][i].c-edge[v][i].f>0){ 28 resi[v][i]=edge[v][i].c-edge[v][i].f; 29 pre[i]=v;qu[qe++]=i;vis[i]=1; 30 }else if(edge[i][v].f>0){ 31 resi[v][i]=edge[i][v].f; 32 pre[i]=v;qu[qe++]=i;vis[i]=1; 33 } 34 } 35 } 36 } 37 } 38 void augment_flow(){ 39 int i=t,j; 40 if(pre[i]==0) {min_augment=0;return;} 41 j=0x7fffffff; 42 while(i!=s){ 43 if(resi[pre[i]][i]<j) j=resi[pre[i]][i]; 44 i=pre[i]; 45 } 46 min_augment=j; 47 } 48 void update_flow(){ 49 int i=t; 50 if(pre[i]==0) return ; 51 while(i!=s){ 52 if(edge[pre[i]][i].c-edge[pre[i]][i].f>0) 53 edge[pre[i]][i].f+=min_augment; 54 else if(edge[i][pre[i]].f>0) edge[pre[i]][i].f+=min_augment; 55 i=pre[i]; 56 } 57 } 58 void solve(){ 59 s=1;t=n; 60 maxflow=0; 61 while(1){ 62 find_augment_path(); 63 augment_flow(); 64 maxflow+=min_augment; 65 if(min_augment>0) update_flow(); 66 else return ; 67 } 68 } 69 int main(){ 70 int i; 71 int u,v,w; 72 while(scanf("%d%d",&m,&n)!=EOF){ 73 memset(edge,0,sizeof(edge)); 74 for(i=0;i<m;i++){ 75 scanf("%d%d%d",&u,&v,&w); 76 edge[u][v].c+=w; 77 } 78 solve(); 79 printf("%d\n",maxflow); 80 } 81 return 0; 82 }