標籤:
Ford_Fulkerson (O(F*E))
感覺不會用到,但還是寫一下吧...
複雜度 : 最大流量為 F ,每次最少增廣 1 ,最多增廣 F 次,每一次最多跑 E 條邊(整張圖).
#include<cstdio>#include<cstring>#include<vector>#include<algorithm>#define rep(i,n) for(int i=0;i<(n);i++)#define for1(i,a,n) for(int i=(a);i<=(n);i++)#define CC(i,a) memset(i,a,sizeof(i))#define read(a) a=getnum()#define print(a) printf("%d",a)using namespace std;const int maxn=205,INF=0x7fffffff;struct edge { int to,cap,rev; };int m,n;bool vis[maxn];vector <edge> g[maxn];inline int getnum(){ int r=0,k=1;char c;for(c=getchar();c<‘0‘||c>‘9‘;c=getchar()) if(c==‘-‘) k=-1;for(;c>=‘0‘&&c<=‘9‘;c=getchar()) r=r*10+c-‘0‘; return r*k; }void add_edge(int from,int to,int cap){ g[from].push_back((edge) { to,cap,g[to].size() }); g[to].push_back((edge) { from,0,g[from].size()-1 });}int dfs(int v,int t,int f){ if(v==t) return f; vis[v]=true; rep(i,g[v].size()) { edge &e=g[v][i]; if(!vis[e.to]&&e.cap>0) { int d=dfs(e.to,t,min(f,e.cap)); if(d>0) { e.cap-=d; g[e.to][e.rev].cap+=d; return d; } } } return 0;}int max_flow(int s,int t){ CC(vis,false); int flow=0,f; while((f=dfs(s,t,INF))>0) { flow+=f; CC(vis,false); } return flow;}void init(){ read(m); read(n); for1(i,1,m) { int from,to,cap; read(from); read(to); read(cap); add_edge(from,to,cap); }}int main(){ init(); print(max_flow(1,n)); return 0;}
Dinic (O(E*V^2))
複雜度 : 每一張層級圖跑完,說明最短增廣路要變長了, 重新 bfs 構造新的層級圖時最短增廣路至少要 +1 ,長度最多為 V - 1 ,所以最多有 ( V - 1 ) 個層級圖.在每一個層級圖中,每一條增廣路都有至少一個瓶頸(路上 cap 最小的弧),跑完這條最短路後這個弧就沒有了(因為走了正向所以反向弧不符合 level ,不會在這一張層級圖中走了),最多 E 條弧,每次至少消去一條,那最多跑 E 次,每一次最多跑 V 個點,所以在一張層級圖裡最多跑 E * V 次,綜上,總複雜度是O(E*V^2).
#include<cstdio>#include<cstring>#include<vector>#include<queue>#include<algorithm>#define rep(i,n) for(int i=0;i<n;i++)#define for1(i,a,n) for(int i=(a);i<=(n);i++)#define CC(i,a) memset(i,a,sizeof(i))#define read(a) a=getnum()#define print(a) printf("%d\n",a)using namespace std;const int maxn=205,INF=0x7fffffff;int m,n;int iter[maxn],level[maxn];struct edge { int to,cap,rev; };vector <edge> g[maxn];inline int getnum() { int r=0,k=1;char c;for(c=getchar();c<‘0‘||c>‘9‘;c=getchar()) if(c==-‘-‘) k=-1;for(;c>=‘0‘&&c<=‘9‘;c=getchar()) r=r*10+c-‘0‘; return r*k; }void add_edge(int from,int to,int cap){ g[from].push_back((edge) { to,cap,g[to].size() }); g[to].push_back((edge) { from,0,g[from].size()-1 });}void bfs(int s){ CC(level,-1); level[s]=1; queue <int> q; q.push(s); while(!q.empty()) { int t=q.front(); q.pop(); rep(i,g[t].size()) { edge &e=g[t][i]; if(level[e.to]<0&&e.cap>0) { level[e.to]=level[t]+1; q.push(e.to); } } }}int dfs(int v,int t,int f){ if(v==t) return f; for(int &i=iter[v];i<g[v].size();i++) { edge &e=g[v][i]; if(e.cap>0&&level[v]<level[e.to]) { int d=dfs(e.to,t,min(f,e.cap)); if(d>0) { e.cap-=d; g[e.to][e.rev].cap+=d; return d; } } } return 0;}int max_flow(int s,int t){ int flow=0; bfs(s); while(level[t]>0) { CC(iter,0); int f; while((f=dfs(s,t,INF))>0) flow+=f; bfs(s); } return flow;}void init(){ read(m); read(n); for1(i,1,m) { int from,to,cap; read(from); read(to); read(cap); add_edge(from,to,cap); }}int main(){ init(); print(max_flow(1,n)); return 0;}
網路流模板