zoukankan      html  css  js  c++  java
  • 图论--网络流初步(最大流,增广路)

    以下内容为提高+难度。
    首先,以一个问题来引入算法:

    最大流问题,该问题描述如下:
    管道网络中每条边的最大通过能力(容量)是有限的,实际流量不超过容量。
    最大流问题(maximum flow problem),一种组合最优化问题,就是要讨论如何充分利用装置的能力,使得运输的流量最大,以取得最好的效果。

    关于最大流问题还有许多定义,具体参见紫书(算法竞赛入门经典)的P366,有详细说明(或者戳这里)。


    对于这个问题,有一个十分经典的算法:增广路算法。
    这个算法每次找到一条路径,记这条路径上的残量最小值为f(f>=1),则将这条路径上的边的残量都减小f,并将总流量flow也增加f。如此重复,直到没有增广路为止,此时的flow便是最大流。
    然后,解决这个问题,比较有效的方法–最短增广路算法,即每次沿着最短的一条增广路进行增广。
    有一种比较优秀的这种算法,Dinic算法。
    我对这个算法还没有清晰的认识,所以我只是贴一下代码(洛谷 P2936 [USACO09JAN]全流Total Flow
    code:

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=10001;
    inline int toint(char ch){
        if(ch>='A'&&ch<='Z'){
            return ch-'A'+1;
        }
        else{
            return ch-'a'+27;
        }
    }
    struct edge{
        int from,to,cap,flow;
    };
    int n,m,s=1,t=toint('Z');
    vector<edge> edges;
    vector<int> G[maxn];
    inline void addedge(int from,int to,int cap){
        edges.push_back((edge){from,to,cap,0});
        edges.push_back((edge){to,from,0,0});
        int m=edges.size();
        G[from].push_back(m-2);
        G[to].push_back(m-1);
    }
    bool vis[maxn];
    int d[maxn];
    int cur[maxn];
    bool bfs(){
        memset(vis,0,sizeof(vis));
        queue<int> q;
        q.push(s);
        vis[s]=1;
        while(!q.empty()){
            int x=q.front();
            q.pop();
            for(int i=0;i<G[x].size();i++){
                edge& e=edges[G[x][i]];
                if(!vis[e.to]&&e.flow<e.cap){
                    vis[e.to]=1;
                    q.push(e.to);
                    d[e.to]=d[x]+1;
                }
            }
        }
        return vis[t];
    }
    int dfs(int x,int a){
        if(x==t||a==0){
            return a;
        }
        int flow=0,f;
        for(int& i=cur[x];i<G[x].size();i++){
            edge& e=edges[G[x][i]];
            if(d[x]+1==d[e.to]&&(f=dfs(e.to,min(a,e.cap-e.flow)))>0){
                e.flow+=f;
                edges[G[x][i]^1].flow-=f;
                flow+=f;
                a-=f;
                if(a==0)break;
            }
        }
        return flow;
    }
    int Maxflow(){
        int flow=0;
        while(bfs()){
            memset(cur,0,sizeof(cur));
            flow+=dfs(s,0x3f3f3f3f);
        }
        return flow;
    }
    int main(){
        scanf("%d",&m);
        for(int i=1;i<=m;i++){
            char ch1,ch2;
            int x,y,l;
            cin>>ch1>>ch2>>l;
            x=toint(ch1);
            y=toint(ch2);
            addedge(x,y,l);
        }
        printf("%d",Maxflow());
        return 0;
    }

    这里再给一道模板题:洛谷 P3376 【模板】网络最大流
    end

  • 相关阅读:
    Sublime Text3 python自动补全问题——Sublime Text3安装Anaconda插件
    微信小程序如何刷新当前界面
    No 'Access-Control-Allow-Origin' header is present on the requested resource——Web Api跨域问题
    云时代架构阅读笔记四——线程池是如何使我们的应用变快的?
    jQuery实现图片放大镜效果
    云时代架构阅读笔记三——架构师比程序员厉害在哪里?
    Ajax学习系列——jQuery中Ajax的请求方式
    读书笔记:梯度是怎么消失的
    读书笔记:初始化神经网络
    读书笔记:对抗过拟合
  • 原文地址:https://www.cnblogs.com/stone41123/p/7581287.html
Copyright © 2011-2022 走看看