1. 程式人生 > >網絡流的$mathfrak{Dinic}$算法

網絡流的$mathfrak{Dinic}$算法

amp 最大 OS HR 性能比較 ace UC 提高 ref

網絡流想必大家都知道,在這不過多贅述。網絡流中有一類問題是讓你求最大流,關於這個問題,許多計算機學家給出了許多不同的算法,在這裏——正如標題所說——我們只介紹其中的一種——\(\tt{Dinic}\)

Dinic是最大流算法中綜合性能比較好的一個算法,它的思想繼承\(Ford-Fulkerson\)算法,但對FF算法有了很大的一個改進。Dinic通過分層圖大大提高了算法效率,減少了許多不必要的搜索。

例題

  • Luogu P3376 【模板】網絡最大流
    正如題目所說,板子題

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm> #include<queue> using namespace std; struct zzz{ int t,len,nex; }e[100010<<2]; int head[10010],tot=1; void add(int x,int y,int z){ e[++tot].t=y; e[tot].len=z; e[tot].nex=head[x]; head[x]=tot; } int vis[10010],s,t; //每次搜索前跑一遍分層圖 bool bfs(){ queue <int> q; memset(vis,0,sizeof
    (vis)); q.push(s); vis[s]=1; while(!q.empty()){ int k=q.front(); q.pop(); for(int i=head[k];i;i=e[i].nex){ int to=e[i].t; if(!vis[to]&&e[i].len){ q.push(to); vis[to]=vis[k]+1; if(to==t) return 1; } } } return vis[t]; } //尋找增廣路徑
    int dfs(int from,int flow){ if(from==t||!flow) return flow; int rest=0,fl; for(int i=head[from];i;i=e[i].nex){ int to=e[i].t; if(vis[to]==vis[from]+1&&(fl=dfs(to,min(flow-rest,e[i].len)))){ e[i].len-=fl; e[i^1].len+=fl; rest+=fl; if(rest==flow) return flow; } } if(rest<flow) vis[from]=0; return rest; } //dinic int dinic(){ int ans=0; while(bfs()) ans+=dfs(s,0x7ffffff); return ans; } inline int read() { int k=0; char c=getchar(); for(;c<'0'||c>'9';) c=getchar(); for(;c>='0'&&c<='9';c=getchar()) k=(k<<3)+(k<<1)+c-48; return k; } int main(){ int n=read(),m=read(); s=read(),t=read(); for(int i=1;i<=m;i++){ int x=read(),y=read(),z=read(); add(x,y,z); add(y,x,0); } printf("%d",dinic()); return 0; }

網絡流的$\mathfrak{Dinic}$算法