标签:
Time Limit: 1000MS | Memory Limit: 10000KB | 64bit IO Format: %I64d & %I64u |
Description
Input
Output
Sample Input
3 3 3 1 10 2 1 2 2 2 1 3 3 1 2 6
Sample Output
7
Source
建图思路很好
此处搬运自AaronPolaris的博客:
构图方式:
①把每个顾客看作除源点和汇点以外的节点。
②从源点向每个猪圈的第一个顾客连一条边,容量为该猪圈最初的猪的数量。
③每个猪圈的前后两个顾客之间连一条边,容量为正无穷。因为可以任意分配每个猪圈中的猪的数量。
④从每个顾客向汇点连一条边,容量为要购买的猪的数量。
搬运完毕
1 //POJ - 1149 PIGS 2 /*by SilverN*/ 3 #include<iostream> 4 #include<algorithm> 5 #include<cstring> 6 #include<cstdio> 7 #include<cmath> 8 #include<queue> 9 using namespace std; 10 const int INF=0xfffff; 11 const int mxn=420;//最大顾客数 12 const int mxm=1200;//最大猪圈数 13 int s,t; 14 int w[mxn][mxn];//容量 15 int d[mxn];//深度 16 int house[mxm];//猪圈里猪数量 17 int last[mxn]; 18 int M,N;//猪圈数,顾客数 19 20 void init(){ 21 int i,j; 22 23 scanf("%d%d",&M,&N); 24 int num; 25 int x; 26 s=0;t=N+1; 27 for(i=1;i<=M;i++)scanf("%d",&house[i]); 28 for(i=1;i<=N;i++){ 29 scanf("%d",&num); 30 for(j=1;j<=num;j++){ 31 scanf("%d",&x); 32 if(!last[x])w[s][i]+=house[x]; 33 //如果是来到此猪圈的第一个顾客,从源点连边到顾客点,容量为猪圈里猪的数量 34 else w[last[x]][i]=INF; 35 //在同一个猪圈的前后顾客之间连边 36 last[x]=i; 37 } 38 scanf("%d",&x); 39 w[i][t]=x;//顾客到汇点连边,容量为欲购买量 40 } 41 return; 42 } 43 bool BFS(int s){ 44 queue<int>q; 45 memset(d,-1,sizeof(d)); 46 q.push(s); 47 d[s]=0; 48 int i; 49 while(!q.empty()){ 50 int u=q.front(); 51 if(u==t)return true; 52 q.pop(); 53 for(i=0;i<=t;i++){ 54 if(w[u][i] && d[i]==-1){ 55 d[i]=d[u]+1; 56 q.push(i); 57 } 58 } 59 } 60 return false; 61 } 62 int DFS(int x,int low){ 63 if(x==t)return low; 64 int i,a; 65 for(i=0;i<=t;i++){ 66 if(w[x][i]>0 && d[i]==d[x]+1) 67 if(a=DFS(i,min(w[x][i],low))){ 68 w[x][i]-=a; 69 w[i][x]+=a; 70 return a; 71 } 72 } 73 return 0; 74 } 75 void dinic(){ 76 int ans=0; 77 int flow=0; 78 while(BFS(s)){ 79 while(flow=DFS(s,INF)){ 80 ans+=flow; 81 } 82 } 83 printf("%d\n",ans); 84 return; 85 } 86 int main(){ 87 init(); 88 dinic(); 89 return 0; 90 }
标签:
原文地址:http://www.cnblogs.com/SilverNebula/p/5589523.html