• Dinic算法最大流入门


    例题传送门

    Dinic算法是网络流最大流的优化算法之一,每一步对原图进行分层,然后用DFS求增广路。时间复杂度是O(n^2*m),Dinic算法最多被分为n个阶段,每个阶段包括建层次网络和寻找增广路两部分。
    Dinic算法的思想是分阶段地在层次网络中增广。它与最短增广路算法不同之处是:最短增广路每个阶段执行完一次BFS增广后,要重新启动BFS从源点Vs开始寻找另一条增广路;而在Dinic算法中,只需一次BFS过程就可以实现多次增广。
    简单来说,分为下面几步:
      1.在剩余网络中查找是否存在从S到T的路径,同时建分层图。
        分层图的层数其实就是S到i这个点需要几步。
      2.沿着分层图多路增广。
        增广时一定要满足dist[j]=dist[i]+1。
      3.直到没有S到T的路径是结束算法。
    code:
    #include <cstdio>
    #include <algorithm>
    #include <vector>
    #include <cstring>
    using namespace std;
    
    char tc()
    {
        static char fl[100000],*A=fl,*B=fl;
        return A==B&&(B=(A=fl)+fread(fl,1,100000,stdin),A==B)?EOF:*A++;
    }
    
    int read()
    {
        char c;while(c=tc(),(c<'0'||c>'9')&&c!='-');
        int x=0,y=1;c=='-'?y=-1:x=c-'0';
        while(c=tc(),c>='0'&&c<='9')x=x*10+c-'0';
        return x*y;
    }
    
    const int MAXN=10005,MAXM=100005;
    
    int N,M,S,T,x,y,c,ans;
    int W[MAXM*2],To[MAXM*2],cnt;
    int l[MAXM*5],h,t,dist[MAXN];
    vector <int> a[MAXN];
    
    bool BFS()
    {
        h=t=0;
        l[++t]=S;
        memset(dist,0,sizeof(dist));dist[S]=1;
            while(h<t){
                int front=l[++h];
                    for(int i=0;i<a[front].size();i++){
                        int to=a[front][i];
                        if(!dist[To[to]] && W[to]){
                            dist[To[to]]=dist[front]+1;
                            l[++t]=To[to];
                        }
                    }
            }
        return dist[T];
    }
    
    int find(int now,int x)
    {
        if(now==T) return x;
            for(int i=0;i<a[now].size();i++){
                int to=a[now][i];
                if(dist[To[to]]==dist[now]+1 && W[to]){
                    int fd=find(To[to],min(x,W[to]));
                    if(fd){
                        W[to]-=fd;
                        W[to^1]+=fd;
                        return fd;
                    }
                }
            }
        return 0;
    }
    
    int main()
    {
        N=read(),M=read(),S=read(),T=read();
            for(int i=1;i<=M;i++){
                 x=read(),y=read(),c=read();
                 W[cnt]=c,To[cnt]=y;a[x].push_back(cnt);cnt++;
                 W[cnt]=0,To[cnt]=x;a[y].push_back(cnt);cnt++;
            }
            while(BFS()){
                ans+=find(S,2e9);
            }
        printf("%d",ans);
        return 0;
    }
  • 相关阅读:
    无缝滚动效果实现
    js模拟滚动条插件一二
    powerDesigner15.1破解
    解决asp.net 中GridView中隐藏过长的数据(使用ToolTip)
    IE6下弹出div覆盖select下拉框
    sql中的常用函数结合实现截取替换功能
    【.NET重修计划】数组,集合,堆栈的问题
    Redis可视化工具推荐
    Redis中String类型的相关命令操作
    Redis的五大数据类型以及key的相关操作命令
  • 原文地址:https://www.cnblogs.com/Cptraser/p/8283308.html
Copyright © 2020-2023  润新知