网络流有点寸步难行了,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;
}