转自百度文库 所以没有连接了。
题意描述:
现在有m个池塘(从1到m开始编号,1为源点,m为汇点),及n条水渠,给出这n条水渠所连接的池塘和所能流过的水量,求水渠中所能流过的水的最大容量.一道基础的最大流题目。http://poj.org/problem?id=1273
参考数据:
输入:
5 4
1 2 40
1 4 20
2 4 20
2 3 30
3 4 10
输出:
50
增广路算法Edmonds_Karp
const int N=201;
const int INF=99999999;
int n,m,sum,s,t;//s,t为始点和终点
int flow[N][N],cap[N][N],p[N];
//flow[u][v]为<u,v>的流量,cap[u][v]为<u,v>容量,
//a[i]表示源点s到节点i的路径上的最小残留量、p[i]记录i的前驱
int Min(int a,int b)
{
return a<=b?a:b;
}
void Edmonds_Karp()
{
int a[201]={0};
int i,u,v;
queue<int> q;//队列 用bfs找增广路径
while(1)
{
memset(a,0,sizeof(a));//每找一次 初始化一次
a[s]=INF;//s为起始点
q.push(s);//原点入队
while(!q.empty())
{
u=q.front();
q.pop();
for(v=1;v<=m;v++)//m是汇点
{
if(!a[v]&&flow[u][v]<cap[u][v])//(流量小于容量与节点v未被访问过)
{//flow[u][v]:为<u,v>的流量,cap[u][v]为<u,v>容量 流量小于容量
p[v]=u;//p[i]记录i的前驱
q.push(v);
a[v]=Min(a[u],cap[u][v]-flow[u][v]);//s-v路径上的最小残留 原点到v的最小残留
}
}
}
if(a[m]==0)//找不到增广路径,则当前流已经是最大流 s到m的最小残留量为0
{
break;
}
sum+=a[m];//流加上
for(i=m;i!=s;i=p[i])//pi记录的是i的前驱,s为原点
{
flow[p[i]][i]+=a[m];//更新正向流量 <u,v> flow[u][v]表示流量 a[m]表示原点s到节点m的最小残留量
flow[i][p[i]]-=a[m];//更新反向流量
}
}
printf("%d\n",sum);
}
int main()
{
int v,u,w;
while(scanf("%d%d",&n,&m)!=EOF)
{
s=1;//从1开始
t=m;//m为汇点
sum=0;//记录最大流量
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;
}