作法就是每次找到一条合计费用最小的从起点到终点剩余容量不为0的路径。
把这条路径灌满水统计一下花费,之后再找新的路径,直到找不到为止。
数据结构方面定义一个构造体表示中两个相邻点的容量,流量和所需费用。
之后定义一个二位数组来标识点和点之间的相邻关系。
代码:
#include <iostream>
using namespace std;
struct Node
{
int cap, flow, cost;
};
Node edge[100][100];
int sum;
int size = 7;
int s = 0, t = 6, a=0;
int pre[10];
int q[200];
int vis[10], dis[10];
void init()
{
int i, j;
for(i = 0; i < size; i++)
for(j = 0; j < size; j++)
{
edge[i][j].cost = 100000;
edge[i][j].flow = 0;
edge[i][j].cap = 0;
}
edge[0][1].cost = 0; edge[0][1].cap = 10000;
edge[1][3].cost = 2; edge[1][3].cap = 8;
edge[1][2].cost = 8; edge[1][2].cap = 7;
edge[3][2].cost = 5; edge[3][2].cap = 5;
edge[3][5].cost = 2; edge[3][5].cap = 9;
edge[2][4].cost = 3; edge[2][4].cap = 9;
edge[5][2].cost = 1; edge[5][2].cap = 2;
edge[5][6].cost = 6; edge[5][6].cap = 5;
edge[4][6].cost = 7; edge[4][6].cap = 10;
edge[4][5].cost = 4; edge[4][5].cap = 6;
}
int spfa()
{
int i, temp;
for(i = 0; i < size; i++)
{
vis[i] = -1;
dis[i] = 100000;
}
int front = 0, tail= 1;
vis[s] = 1; dis[s] = 0;
q[front] = s;
while(front < tail)
{
temp = q[front];
vis[temp] = -1;
front++;
for(i = 0; i < size; i++)
{
int res = edge[temp][i].cap - edge[temp][i].flow;
if(res > 0 && dis[i] > dis[temp] + edge[temp][i].cost)
{
dis[i] = dis[temp] + edge[temp][i].cost;
pre[i] =temp;
if(vis[i] == -1)
{
vis[i] = 1;
q[tail++] = i;
}
}
}
}
return dis[t];
}
int MCMF()
{
int temp, min, flow, sum = 0, cost, val;
while(spfa() < 8000)
{
temp = t;
flow = 100000; cost = 0;
while(temp != s)
{
val = edge[pre[temp]][temp].cap - edge[pre[temp]][temp].flow;
cost += edge[pre[temp]][temp].cost;
if(val < flow)
flow = val;
temp = pre[temp];
}
temp = t;
cout << flow << " " << cost << endl;
sum += flow * cost;
while(temp != s)
{
edge[pre[temp]][temp].flow += flow;
edge[temp][pre[temp]].flow -= flow;
// cout << pre[temp] << " " << temp << " ";
// cout << edge[pre[temp]][temp].flow << endl;
temp = pre[temp];
}
}
return sum;
}
int main()
{
init();
cout << MCMF() << endl;
return 0;
}