转自百度文库 所以没有连接了。
现在有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
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; }