最大流定理
如果残留网络上找不到增广路径,则当前流为最大流;反之,如果当前流不为最大流,则一定有增广路径。
这里涉及到了一个
残留网络.
如果已经理解了什么是最大流,算法说起来就比较好理解了,在每次找到一条增广路之后,就去更新它的流量(正反向都要更新),每次更新后再继续找增广路,切记要把path
清零(重新赋值-1),你可能会纳闷这样每次的bfs的不都一样了吗,把path又都给清了。。。可不是那样的啊~因为在每次我们找到一条增广路后,我们是不是都更新了它的正反向流量,每次改变后可能有某一条路径的可行流量为0了,就是不能再流通了,所以这样会更改一条新的路径,不会说有重复的路径~建议动手调试下程序嘿嘿,我也是看了好久的最大流(只是字面上理解最大流的皮毛概念),真的是特别久啊,最痛苦的就是我连题的测试数据我都看不懂~昨天晚上我终于开窍了,然后就开开心心的回宿舍了,今天开始做最大流的题了,超开心

/*
Sample Input
5 4
1 2 40
1 4 20
2 4 20
2 3 30
3 4 10
Sample Output
50
*/
#include<stdio.h>
#include<string.h>
#include<queue>
using namespace std;
#define inf 1<<31-1
#define min(a,b) a<b?a:b
int path[201];
int flow[201];
int map[201][201];
int start,end;
int bfs()
{
memset(path,-1,sizeof(path));
int i,j,t;
queue<int>Q;
path[start]=0;
flow[start]=inf;
Q.push(start);
while(!Q.empty())
{
t=Q.front();
Q.pop();
if(t==end) break;
for(i=1;i<=end;i++)
{
if(i!=start && map[t][i] && path[i]==-1 )
{
flow[i]=min(flow[t],map[t][i]);
path[i]=t;
Q.push(i);
}
}
}
if(path[end]==-1) return -1;
return flow[end];
}
int Edmords_Karp()
{
int max_flow=0,i,ff,pre,now;
while((ff=bfs())!=-1)
{
max_flow+=ff;
now=end;
while(now!=start)
{
pre=path[now];
map[pre][now]-=ff;
map[now][pre]+=ff;
now=pre;
}
}
return max_flow;
}
int main()
{
int n,m,i,u,v,cost;
while(~scanf("%d%d",&n,&m))
{
memset(map,0,sizeof(map));
for(i=0;i<n;i++)
{
scanf("%d%d%d",&u,&v,&cost);
map[u][v]+=cost;
}
start=1;
end=m;
printf("%d\n",Edmords_Karp());
}
return 0;
}