• 最大网络流算法


    最大网络流,需要的准备是: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;
    }
  • 相关阅读:
    二叉树线索化。。。
    如何通过指针访问虚函数表,并且调用里面的方法
    进程间通信IPC
    什么时候该用assert
    高并发服务端分布式系统设计概要(上)
    C语言读写文件
    Linux 与 BSD 有什么不同?
    extern "C" 使用
    C语言字符数组的定义与初始化
    Linux守护进程
  • 原文地址:https://www.cnblogs.com/acmblog/p/9648998.html
Copyright © 2020-2023  润新知