解题思路:
这是一道典型的模板题,直接套用EK算法即可。。。我感觉最大流的本质就是能否找到一个从源点到汇点的增广路径,并将其最小的边作为增加值,沿着增广路上的边进行更新。
AC:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const int maxn = 200;
const int inf = 0x7fffff;
int n,m,s,t,map[maxn][maxn],path[maxn]; //map[i][j]存储(i,j)的流,path存储的是增广路径
int flow[maxn]; //flow存储一次BFS遍历之后流的可改进量
int bfs() //寻找一条增广路径
{
queue<int> q;
memset(path,-1,sizeof(path));
flow[s] = inf;
q.push(s);
while(!q.empty())
{
int now = q.front();
q.pop();
if(now == t) break;
for(int i = 1; i <= m; i++)
{
if(i != s && path[i] == -1 && map[now][i])
{
flow[i] = flow[now] < map[now][i] ? flow[now] : map[now][i];
q.push(i);
path[i] = now;
}
}
}
if(path[t] == -1) return -1; //找不到增广路径
return flow[t];
}
int Edmonds_Karp()
{
int max_flow = 0,step,now,pre;
while((step = bfs()) != -1) //能够找到一条增广路径
{
max_flow += step;
now = t;
while(now != s)
{
pre = path[now];
map[pre][now] -= step;
map[now][pre] += step;
now = pre;
}
}
return max_flow;
}
int main()
{
while(cin>>n>>m)
{
int u,v,cost;
memset(map,0,sizeof(map));
for(int i = 1; i <= n; i++)
{
cin>>u>>v>>cost;
map[u][v] += cost;
}
s = 1; t = m;
printf("%d\n",Edmonds_Karp());
}
return 0;
}