zoukankan      html  css  js  c++  java
  • 不一样的网络流系列——Dinic跑得快

    前言

    摆王兴致冲冲地跑到我们机房来对我说跟你讲一个黑科技。。。

    Dinic的神奇优化

    Dinic优化

    我们发现如果Dinic不建反向边会跑的飞起(当然Wa是必然的)
    所以考虑在加反向边的基础上优化.

    首先我们记录网络中最大的一个流量,设它为Min,然后:

    1. 把所有小于Min的边都加入网络中
    2. 最大流+=Dinic()
    3. Min /= 2
    4. 到1
      然后在Dinic时不走反向边(但是值要改变),最后在可以走反向边的情况下再来一次

    注意bfs的一些操作,如果不当会溢出...

    代码实现

    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #include<math.h>
    #include<algorithm>
    #include<queue>
    #include<set>
    #include<map>
    #include<iostream>
    using namespace std;
    #define ll long long
    #define re register
    #define file(a) freopen(a".in","r",stdin);freopen(a".out","w",stdout)
    #define int ll
    inline int gi()
    {
        int f=1,sum=0;char ch=getchar();
        while(ch>'9' || ch<'0'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0' && ch<='9'){sum=(sum<<3)+(sum<<1)+ch-'0';ch=getchar();}
        return f*sum;
    }
    const int N=500010,M=2000010,Inf=1e10+10;
    int n,m,s,t,ans,dep[N],cur[N];
    struct node
    {
        int u,v,c;
    }E[M];
    vector<int>front[N];
    vector<node>e;
    void Add(int u,int v,int c)
    {
        e.push_back((node){u,v,c});
        e.push_back((node){v,u,0});
        front[u].push_back(e.size()-2);
    }
    bool cmp(node a,node b)
    {
        return a.c>b.c;
    }
    queue<int>Q;
    bool bfs()
    {
        memset(dep,127,sizeof(dep));
        Q.push(s);dep[s]=0;
        while(!Q.empty())
        {
            int u=Q.front();Q.pop();
            for(int i=0;i<front[u].size();i++)
            {
                int id=front[u][i];
                int v=e[id].v;
                if(dep[v]>1e9 && e[id].c) 
                {
                    dep[v]=dep[u]+1;
                    Q.push(v);
                }
            }
        }
        return dep[t]<1e9;
    }
    int dfs(int u,int flow) 
    {
    //	printf("%lld %lld
    ",u,flow);
        if(!flow || u==t)return flow;
        int F=0;
        for(int &i=cur[u];i<front[u].size();i++) 
        { 
            int id=front[u][i];
            if(dep[e[id].v]==dep[u]+1 && e[id].c) 
            { 
                int di=dfs(e[id].v,min(flow,e[id].c)); 
                if(di)
                {
                    e[id].c-=di;e[id^1].c+=di;
                    flow-=di;F+=di;
                    if(!flow)break;
                }
                else dep[e[id].v]=0;
            }
        }
        return F;
    }
    int Dinic()
    {
        int flow=0;
        while(bfs())
        {
            for(int i=1;i<=n;i++)cur[i]=0;
            while(int d=dfs(s,Inf))flow+=d;
        }
        return flow;
    }
    signed main()
    {
        n=gi();m=gi();s=gi();t=gi();
        for(int i=0;i<m;i++)
        {
            int u=gi(),v=gi(),c=gi();
            E[i]=(node){u,v,c};
        }
        sort(E,E+m,cmp);
        for(int type=0;type<2;type++){
            for(int p=1<<30,now=0;p;p>>=1)
            {
                while(now<m && E[now].c>=p)
                {
                    if(!type)Add(E[now].u,E[now].v,E[now].c);
                    else front[E[now].v].push_back(now*2+1);
                    now++;
                }
                ans+=Dinic();
            }
        }
        printf("%lld
    ",ans);
        return 0;
    }
    
  • 相关阅读:
    POJ-3083 Children of the Candy Corn (BFS+DFS)
    HDU-1429 胜利大逃亡(续) (BFS+状态压缩)
    【JS】408- 看一看 JavaScript 引擎是什么
    【HTTPS】407- 记住 HTTPS!
    【React】406- React Hooks异步操作二三事
    【Git】405- 分享:大牛总结的 Git 使用技巧
    【性能优化】404- 从 12.67s到1.06s 性能优化实战
    【HTTP】402- 深入理解http2.0协议,看这篇就够了!
    【Web技术】401- 在 React 中使用 Shadow DOM
    7.app和app后端的通讯
  • 原文地址:https://www.cnblogs.com/mleautomaton/p/10327978.html
Copyright © 2011-2022 走看看