经典的最大流 POJ 1273

来源:互联网 发布:淘宝的劲霸官方旗舰店 编辑:程序博客网 时间:2024/05/23 16:57

转自百度文库 所以没有连接了。

题意描述:

现在有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;}


原创粉丝点击