您的位置:首页 > 理论基础 > 计算机网络

网络最大流poj1273,hdoj1532

2014-08-10 11:45 316 查看
看了几天关于最大流的书,今天找一道最经典的最大流题目hdoj1532,跟poj1273一样的题目,起初WA了,不知道什么原因。后来在POJ的discuss看到,原来是重边的问题,对该细节疏忽了。然后把代码改了一下,AC。

这里用的是增广路算法——Edmons-Karp。算法思想是,从零流(所有边的流量均为0)开始不断增加流量,保持每次增加流量后都满足容量限制、斜对称性和流量平衡3个条件。

这个算法基于这样的一个事实:残量网络中任何一条从s到t的有向道路都对应一条原图中的增广路——只要求出该道路中所有残量的最小值d,把对应的所有边上的流量增加d即可,这个过程称为增广。不难验证,如果增广前的流量满足3个条件,增广后仍然满足。只要在残量网络中存在增广路,流量就可以增大;如果残量网络中不存在增广路,则当前流就是最大流。(寻找任意路径用的是广度搜索)

//poj1273,hdoj1532模板代码 注意重边!
//s为源点,t为汇点,f为s-t净流量
#include <iostream>
#include <queue>
#include <string.h>
#define N 250
#define MaxInt 0x3f3f3f3f
using namespace std;
int m,n,flow

,cap

,a
,p
;
queue<int> q;
 
int MaxFlow(int s,int t)
{
    int f,u,v;
    memset(flow,0,sizeof(flow));
    f=0;
    while(1)
    {
        memset(a,0,sizeof(a));
        a[s]=MaxInt;
        q.push(s);
        //BFS找增广路
        while(!q.empty())
        {
            u=q.front();q.pop();
            for(v=1;v<=n;v++)
            {
                if(!a[v]&&cap[u][v]>flow[u][v])//找到新结点v
                {
                    p[v]=u;q.push(v);//记录v的父亲,并加入FIFO队列
                    a[v]=a[u]<cap[u][v]-flow[u][v]?a[u]:cap[u][v]-flow[u][v];//a[v]为s-v路径上的最小流量
                }
            }
        }
        if(a[t]==0) break;//找不到,则当前已是最大流量
        for(v=t;v!=s;v=p[v])//从汇点往回走
        {
            flow[p[v]][v]+=a[t];//更新正向流量
            flow[v][p[v]]-=a[t];//更新反向流量
        }
        f+=a[t];//更新从s流出的总流量
    }
    return f;
}
 
int main()
{
    int u,v,i,c,ans;
    while(scanf("%d%d",&m,&n)!=EOF)
    {
        memset(cap,0,sizeof(cap));
        for(i=0;i<m;i++)
        {
            scanf("%d%d%d",&u,&v,&c);
            cap[u][v]+=c;
        }
        ans=MaxFlow(1,n);
        printf("%d\n",ans);
    }
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: