题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1532
http://poj.org/problem?id=1273
题目翻译:
有N个管道,M个点,然后给出N个管道的容量,求点1到点M的最大流量。
最大流的入门题。代码参考网上的模板。
#include <iostream>
#include <queue>
#include <stdio.h>
#include <string.h>
using namespace std;
const int maxn = 205;
const int maxm = 205;
const int INF = 2*1e9+10;
int N,M,s,d; ///这个题目中N是管道数,M是节点数
int flow[maxn][maxn]; ///u->v的流量
int cap[maxn][maxn]; ///u->v的容量
int minFlow[maxn]; ///源点s到节点i的路径上的最小残留量
int pre[maxn]; ///pre[i]记录i的前驱
int maxFlow; ///记录最大流
void Edmonds_Karp()
{
int u,v;
maxFlow = 0;
queue<int>qu; ///使用队列,BFS找增广路径
while(true)
{
memset(minFlow,0,sizeof(minFlow));
minFlow[s] = INF;
qu.push(s);
while(!qu.empty())
{
u = qu.front();
qu.pop();
for(v = 1; v <= M; v++)
{
if(minFlow[v]==0 && flow[u][v] < cap[u][v])
{
pre[v] = u;
qu.push(v);
minFlow[v] = min(minFlow[u],cap[u][v]-flow[u][v]); ///求s->v路径上的最小残余量
}
}
}
if(minFlow[d] == 0) ///如果s到d路径上的最小残余量是0的话,则当前结果就是最大流
break;
maxFlow = maxFlow + minFlow[d];
for(v = M; v != s; v = pre[v]) ///从汇点顺着这条路径往回走
{
u = pre[v];
flow[u][v] += minFlow[d];
flow[v][u] -= minFlow[d];
}
for(int i = 1; i <= M; i++)
{
for(int j = 1; j <= M; j++)
printf("%d ",flow[i][j]);
printf("\n");
}
}
printf("%d\n",maxFlow);
}
int main()
{
int u,v,w;
while(~scanf("%d%d",&N,&M))
{
s = 1;
d = M;
memset(flow,0,sizeof(flow));
memset(cap,0,sizeof(cap));
while(N--)
{
scanf("%d%d%d",&u,&v,&w);
cap[u][v] += w;
}
Edmonds_Karp();
}
return 0;
}