#include <iostream>
using namespace std;
int M,N;
int cost[205][205],r;
int Min[205],pre[205];
bool visit[205]; //搜索标记
int bfs()
{
int q[205], start = 0, end = 0;
memset(visit,false,sizeof(visit));
q[0] = 1; //搜索起点
Min[1] = 100000;
visit[1] = true;
while (start <= end)
{
int t = q[start]; //下面进行点t的广搜
for (int i = 1; i <= M; i++)
{
if (!visit[i] && cost[t][i] != 0)
{
//Min[t],最小值传递;如果前向节点记录的值比当前的边的值要大,则...
Min[i] = Min[t] < cost[t][i] ? Min[t] : cost[t][i]; //Min[t]的作用是记录路径中权值最小的边
pre[i] = t; //i的前向节点为t,在搜索过程中不断更新
if (i == M)
{
return Min[i]; //搜索完毕
}
visit[i] = true;
q[++end] = i; //将i并入已搜索的集合,q相当于广搜的队列。
}
}
start++;
}
return -1;
}
void fork_fulkerson()
{
int max = 0, t,pre_t;
while ((r=bfs())!= -1) //存在增广路径
{
max += r; //最后max的值将是最大流的值
t = M;
while(t != 1)
{
pre_t = pre[t]; //找出前向点
cost[pre_t][t] -= r; //前向路径值减r
cost[t][pre_t] += r; //后向路径值加r
t= pre_t; //更新前向点
}
}
printf("%d\n",max);
}
int main()
{
int x, y, k;
while (scanf("%d %d", &M, &N)!=EOF)
{
memset(cost, 0, sizeof(cost));
for (int i = 1; i <= N; i++)
{
scanf("%d %d %d", &x, &y, &k);
cost[x][y] += k;
}
fork_fulkerson();
}
}
测试数据:
input:
2 1
1 2 3
4 5
1 2 9
2 3 7
3 4 6
2 4 4
1 3 1
5 7
1 2 1
1 3 2
1 4 3
2 5 4
3 2 3
4 3 3
3 5 2
output:
3
10
6