网络流有点寸步难行了,http://blog.sina.com.cn/s/blog_6635898a0100pabw.html 看这个博客写的代码,自己大致理解了一下,作为最小费用流的邻接矩阵实现的模板。
//288K 250ms #include <iostream> using namespace std; const int Max = 110; const int inf = 0x7fffffff; int cost[Max][Max]; int cap[Max][Max]; int que[Max], pre[Max]; bool vis[Max]; int dis[Max]; int n, ans; bool spfa() { int i, f, r; memset(vis, false, sizeof(vis)); for(i = 0; i <= n; i++) dis[i] = inf; que[0] = 0; dis[0] = 0; f = 0; r = 1; while(f != r) { int cur = que[f++]; if(f == Max) f = 0; vis[cur] = false; for(i = 0; i <= n; i++) if(cap[cur][i] && dis[i] > dis[cur] + cost[cur][i]) { dis[i] = dis[cur] + cost[cur][i]; pre[i] = cur; if(!vis[i]) { vis[i] = true; que[r++] = i; if(r == Max) r = 0; } } } if(dis[n] == inf) return false; else return true; } void end() { int i, tmp = inf; for(i = n; i; i = pre[i]) if(tmp > cap[pre[i]][i]) tmp = cap[pre[i]][i]; for(i = n; i; i = pre[i]) { cap[pre[i]][i] -= tmp; cap[i][pre[i]] += tmp; ans += tmp*cost[pre[i]][i]; } } int main() { int i, j, k; int N, M, K; int order[Max/2][Max/2], storage[Max/2][Max/2]; int needK[Max/2], haveK[Max/2]; bool flag; freopen("a.txt", "r", stdin); while(scanf("%d%d%d", &N, &M, &K) && N) { memset(needK, 0, sizeof(needK)); memset(haveK, 0, sizeof(haveK)); n = N+M+1; // 超级汇点 ans = 0; for(i = 1; i <= N; i++) { for(j = 1; j <= K; j++) { scanf("%d", &order[i][j]);// 第i个客户需要第j种货物的量 needK[j] += order[i][j]; } } for(i = 1; i <= M; i++) { for(j = 1; j <= K; j++) { scanf("%d", &storage[i][j]); haveK[j] += storage[i][j]; } } flag = true; for(i = 1; i <= K; i++) if(needK[i] > haveK[i]) { flag = false; break; } for(k = 1; k <= K; k++)// 枚举k种货物,对每种货物求最大流 { memset(cap, 0, sizeof(cap)); for(i = 1; i <= N; i++) for(j = 1; j <= M; j++) { scanf("%d", &cost[j][M+i]); cost[M+i][j] = -cost[j][M+i]; cap[j][M+i] = inf; } if(!flag) continue; // 当货物不够时,返回继续输入数据 for(i = 1; i <= M; i++) { cap[0][i] = storage[i][k]; cost[0][i] = cost[i][0] = 0;// 从超级源点到每一个货物提供点的运费为0 } for(i = 1; i <= N; i++) { cap[i+M][n] = order[i][k]; cost[i+M][n] = cost[n][i+M] = 0; } while(spfa()) {end();} } if(flag) printf("%d\n", ans); else printf("-1\n"); } return 0; }