POJ 2516 Minimum Cost(最小费用最大流)
这个题目,建图我是按
源点->(有流量无费用)->人->(无穷的流量有费用)->仓库->(有流量无费用)->汇点
建图没弄好wa了一次。剩下就是模版了。。
1 #include <cstdio> 2 #include <cstring> 3 #include <cmath> 4 #include <queue> 5 using namespace std; 6 #define INF 0x7fffffff 7 8 int pd[51][51]; 9 int im[51][51]; 10 int cc[51][51][51]; 11 12 int low[1001],path[1001]; 13 int first[1001],in[1001],dis[1001]; 14 int str,end,t; 15 struct node 16 { 17 int u,v,w,cost,re,next; 18 }edge[101*101]; 19 int sp,cf; 20 void CL() 21 { 22 t = 1; 23 memset(first,-1,sizeof(first)); 24 } 25 void add(int u,int v,int w,int cost) 26 { 27 edge[t].u = u; 28 edge[t].v = v; 29 edge[t].w = w; 30 edge[t].cost = cost; 31 edge[t].re = t+1; 32 edge[t].next = first[u]; 33 first[u] = t ++; 34 35 edge[t].u = v; 36 edge[t].v = u; 37 edge[t].w = 0; 38 edge[t].cost = -cost; 39 edge[t].re = t-1; 40 edge[t].next = first[v]; 41 first[v] = t ++; 42 } 43 int bfs() 44 { 45 int u,i,v; 46 memset(path,-1,sizeof(path)); 47 for(i = 0;i <= end;i ++) 48 { 49 dis[i] = INF; 50 in[i] = 0; 51 } 52 queue<int>que; 53 que.push(str); 54 dis[str] = 0; 55 in[str] = 1; 56 low[str] = INF; 57 while(!que.empty()) 58 { 59 u = que.front(); 60 in[u] = 0; 61 que.pop(); 62 for(i = first[u];i != -1;i = edge[i].next) 63 { 64 v = edge[i].v; 65 if(edge[i].w&&dis[v] > dis[u]+edge[i].cost) 66 { 67 dis[v] = dis[u] + edge[i].cost; 68 path[v] = i; 69 low[v] = low[u] < edge[i].w ? low[u]:edge[i].w; 70 if(!in[v]) 71 { 72 que.push(v); 73 in[v] = 1; 74 } 75 } 76 } 77 } 78 if(path[end] == -1) 79 return -1; 80 else 81 return low[end]; 82 83 } 84 void mcmf() 85 { 86 int res,temp,now; 87 while((res = bfs()) != -1) 88 { 89 now = end; 90 cf += res; 91 while(now != str) 92 { 93 temp = path[now]; 94 edge[temp].w -= res; 95 edge[edge[temp].re].w += res; 96 sp += res*edge[temp].cost; 97 now = edge[temp].u; 98 } 99 } 100 } 101 int main() 102 { 103 int n,m,k,u,ans,sum,i,j; 104 while(scanf("%d%d%d",&n,&m,&k)!=EOF) 105 { 106 if(!n&&!m&&!k) break; 107 for(i = 1;i <= n;i ++) 108 { 109 for(j = 1;j <= k;j ++) 110 scanf("%d",&pd[i][j]); 111 } 112 for(i = 1;i <= m;i ++) 113 { 114 for(j = 1;j <= k;j ++) 115 scanf("%d",&im[i][j]); 116 } 117 for(i = 1;i <= k;i ++) 118 { 119 for(j = 1;j <= n;j ++) 120 { 121 for(u = 1;u <= m;u ++) 122 scanf("%d",&cc[i][j][u]); 123 } 124 } 125 str = 0; 126 end = n+m+1; 127 ans = 0; 128 for(i = 1;i <= k;i ++) 129 { 130 CL(); 131 sum = 0; 132 for(j = 1;j <= n;j ++) 133 { 134 add(str,j,pd[j][i],0); 135 sum += pd[j][i]; 136 } 137 for(j = 1;j <= m;j ++) 138 add(n+j,end,im[j][i],0); 139 for(j = 1;j <= n;j ++) 140 { 141 for(u = 1;u <= m;u ++) 142 add(j,n+u,INF,cc[i][j][u]); 143 } 144 sp = cf = 0; 145 mcmf(); 146 if(cf < sum) break; 147 ans += sp; 148 } 149 if(i == k+1) 150 printf("%d\n",ans); 151 else 152 printf("-1\n"); 153 } 154 return 0; 155 }