最大网络流算法

Posted acmblog

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了最大网络流算法相关的知识,希望对你有一定的参考价值。

最大网络流,需要的准备是:BFS,EK算法

用pre数组记录前驱节点,用vis判断是否访问过

用g二维数组表示残余网络,用f二维数组表示实际流网络

下面这篇博客详细介绍了最大网络流:既然已经有了轮子,那我就不造了

https://www.cnblogs.com/zsboy/archive/2013/01/27/2878810.html

下面是我的代码

#include<iostream>
#include<queue>
#include<cstring>
#include<iomanip>
using namespace std;
const int maxn=100;
const int INF=9999999;
int g[maxn][maxn];//残余网络,初始值为最大流量
int f[maxn][maxn];//实流网络,初始值都是零
int pre[maxn];//存储前驱节点
bool vis[maxn];//判断是否访问过
int n,m;
bool bfs(int s,int t)
{
    memset(pre,-1,sizeof(pre));
    memset(vis,false,sizeof(vis));
    vis[s]=true;
    queue<int> que;
    que.push(s);
    while(!que.empty())
    {
        int now=que.front();
        que.pop();
        for(int i=1;i<=n;i++)
        {
            if(!vis[i]&&g[now][i]>0)//g[now][i]>0这个条件保证了bfs不会重复搜索 
            {
                vis[i]=true;
                pre[i]=now;
                if(i==t)    return true;
                que.push(i);
            }
        }
    }
    return false;
}
int EK(int s,int t)
{
    int v,w,d,maxflow;
    maxflow=0;
    while(bfs(s,t))
    {
        d=INF;
        v=t;
        while(v!=s)
        {
            w=pre[v];
            if(d>g[w][v])    d=g[w][v];
            v=w;
        }
        maxflow+=d;
        v=t;
        while(v!=s)
        {
            w=pre[v];
            g[w][v]-=d;
            g[v][w]+=d;
            if(f[v][w]>0)
            f[v][w]-=d;
            else
            f[w][w]+=d;
            v=w;
        }
    }
    return maxflow;
}
int main()
{
    int u,v,w;
    cin>>n>>m;
    memset(g,0,sizeof(g));
    memset(f,0,sizeof(f));
    for(int i=1;i<=m;i++)
    {
        cin>>u>>v>>w;
        g[u][v]+=w;
    }
    cout<<EK(1,n)<<endl;
    return 0;
}

 

以上是关于最大网络流算法的主要内容,如果未能解决你的问题,请参考以下文章

网络最大流——EK算法详解

模板网络最大流

网络流最大流之Dinic算法

网络流最大流入门(Dinic算法)模板

网络流(最大流)Ford_Fulkerson算法 白书

试题库问题(最大流Isap) 网络流