演算法_dinic最大流

來源:互聯網
上載者:User

標籤:組成   img   splay   表示   最小   TE   namespace   turn   max   

網路流是什嗎?

不急我們慢慢來講。

首先我們先看看最大流1.背景

管道網路中每條邊的最大通過能力(容量)是有限的,實際流量不超過容量。最大流問題(maximum flow problem),一種組合最佳化問題,就是要討論如何充分利用裝置的能力,使得運輸的流量最大,以取得最好的效果。求最大流的標號演算法最早由福特和福克遜與與1956年提出,20世紀50年代福特(Ford)、(Fulkerson)建立的“網路流理論”,是網路應用的重要組成成分。

2.定義(這很重要!!!)

1)源點:只有流出去的點

2)匯點:只有流進來的點

3)流量:一條邊上流過的流量

4)容量:一條邊上可供流過的最大流量

5)殘量:一條邊上的容量-流量

2.性質

1)對於任何一條流,總有流量<=容量(流經的邊的最小流量),即
\[flow<=min \left\{cur_{i}\right\}(cur_i\in flow_{now})\]
2)對於任何一條有向邊(u,v),總有
\[cur(u,v)=-cur(v,u)\]

3.演算法思想(增廣路dinic)

1.找到一條從源點到匯點的路徑,使得路徑上任意一條邊的殘量>0(注意是小於而不是小於等於,這意味著這條邊還可以分配流量),這條路徑便稱為增廣路

2.找到這條路徑上最小的\(F[u][v]\)(我們設\(F[u][v]\)表示\(u->v\)這條邊上的殘量即剩餘流量),下面記為\(flow\)

3.將這條路徑上的每一條有向邊\(u->v\)的殘量減去\(flow\),同時對於起反向邊\(v->u\)的殘量加上\(flow\)(為什麼呢?我們下面再講)

4.重複上述過程,直到找不出增廣路,此時我們就找到了最大流

這個圖很詳細的給出了增廣路的過程,其實這就是dinic演算法的思想

4.時間複雜度

dinic演算法其實就是一種暴力,時間複雜度
\[O(n^2m)\]
這其實十分暴力了,如果\(m=\frac{n(n-1)}{2}\)d的話,那麼時間複雜度將達到
\[O(\frac{n^3(n-1)}{2})\]
省略常數後也就是
\[O(n^4)\]
這是極其恐怖的複雜度,當然如果出題人不故意卡的話,一般沒什麼問題

5.代碼實現
#include<iostream>#include<cstdio>#include<cstring>#include<queue>#define Maxn 1000001#define INF 0x7fffffff#define maxN 1000001#define maxM 1000001using namespace std;class Dinic{    private:        int cnt;//邊的數量,從0開始編號。        int head[Maxn];//每一個點最後一條邊的編號        int next[Maxn];//指向對應點的前一條邊        int v[Maxn];//每一條邊指向的點        int w[Maxn];//每一條邊的殘量        int n,s,t;//源點和匯點        int depth[Maxn];//分層圖中標記深度        void add_edge(int x,int y,int z){            next[++cnt]=head[x];            v[cnt]=y;            w[cnt]=z;            head[x]=cnt;            return;        }    public:        void init(int x,int y,int z){//初始化            n=x,s=y,t=z;            cnt=-1;            memset(head,-1,sizeof(head));            memset(next,-1,sizeof(next));            return;        }        void addedge(int x,int y,int z){            add_edge(x,y,z);            add_edge(y,x,0);            return;        }        bool bfs(){//廣搜找分層圖             queue<int>q;            memset(depth,0,sizeof(depth));            depth[s]=1;            q.push(s);            do{                int u=q.front();                q.pop();                for(int i=head[u];~i;i=next[i]){                    if(w[i]>0 and !depth[v[i]]){                        depth[v[i]]=depth[u]+1;                        q.push(v[i]);                    }                }            }while(!q.empty());            return depth[t];        }        int dfs(int u,int now){            if(u==t)                return now;            for(int i=head[u];~i;i=next[i]){                if(w[i]>0 and depth[v[i]]==depth[u]+1){                    int d=dfs(v[i],min(now,w[i]));                    if(d>0){                        w[i]-=d;w[i^1]+=d;                        return d;                    }                }            }            return 0;        }        int dinic(){//dinic演算法主過程            int ans=0;            while(bfs()){                int x;                while(x=dfs(s,INF))                    ans+=x;            }            return ans;        }}dinic;int n,m,s,t;int main(){    scanf("%d%d%d%d",&n,&m,&s,&t);    dinic.init(n,s,t);    for(int i=1;i<=m;i++){        int x,y,z;        scanf("%d%d%d",&x,&y,&z);        dinic.addedge(x,y,z);    }    printf("%d\n",dinic.dinic());    return 0;}
6.最大流能解決的問題

網路流的問題其實有著很大的共性,首先就是他們都是只需要求一個的答案,且不需要中間的過程,還有答案是某種最值,往往這就是網路流。而網路流也不是裸的,往往需要各種建模亂搞。

演算法_dinic最大流

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.