網路流演算法總結

2021-12-29 21:33:04 字數 3229 閱讀 8821

該演算法主要求的是,在乙個有向圖中,每條邊上有乙個最大流量,求從源點到匯點的最大流量。一般求解這類問題主要有以下幾種演算法。

增廣路ek演算法

這個演算法的主要思想很簡單,就是不斷bfs尋找增廣路並往裡頭新增流量,直到無法搜出增廣路,此時從源點流出的流量即為最大流。注意其中的反流量概念,即flow[u][v]=?flow[v][u]

該演算法時間複雜度上限為o(v?e2),不過一般到不了這個複雜度。

下面直接附上**:

#include

#include

#include

#include

using namespace std;

const int inf=1e+9;

const int maxn=200+10;

int c[maxn][maxn],f[maxn][maxn],p[maxn],pre[maxn],d[maxn<<4];

int main()

int flag=1;

while(flag)

}if(flag)break;

}if(!flag)break;

t=n;int min=inf;

while(pre[t])

}int ans=0;

for(i=1;i<=n;i++)

ans+=f[1][i];

printf("%d\n",ans);

return 0;

}dinic演算法

與ek演算法不同的是,dinic演算法每次要對有向圖進行一次bfs,對這張圖進行分層,得到圖上的每乙個點的層數。再進行dfs搜尋增廣路,增廣路只能從這一層到下一層。若不存在增廣路,則重複上述過程,對這張圖重新分層,直到無法搜到增廣路為止。

該演算法的時間複雜度的理論上限為o(n2m),不過同樣地,一般到不了這個複雜度。甚至在用dinic演算法做二分圖匹配時,複雜度能到o(n√?m)。

下面附上**:

#include

#include

#include

#include

#include

#include

using namespace std;

typedef long long ll;

const int inf=1e9;

const int maxm=1e5+10;

const int maxn=1e4+10;

int nex[maxm<<1],beg[maxm<<1],to[maxm<<1],flow[maxm<<1],q[maxn],lev[maxn];

int e=1,n;

inline int read()

inline void add(int x,int y,int z)

int bfs(int s,int t)

}return 0;

}int dfs(int x,int goal,int maxflow)

}return 0;

}int main()

int ans=0;

while(bfs(s,t))

ans+=dfs(s,t,inf);

printf("%d\n",ans);

return 0;

}isap演算法

isap演算法則在dinic演算法的基礎上又進行了一些優化。dinic演算法需要對殘餘流量進行多次分層,而isap只需要進行一次,甚至你可以不進行預處理分層(如下文中的**就沒有預處理分層)。dinic演算法在増廣後遇到沒有滿足條件的增廣路後,會對殘餘流量進行重新分層,而isap則會將level[x]重置為min(level[i])+1,其中i到x有一條有向邊。

但僅僅有這個優化是不夠的,isap的最大的優化來自gap優化。

gap優化就是看殘餘網路有無斷層的情況(即其中任何乙個節點都不屬於某一層),若有的話直接退出即可。

isap的優化是非常明顯的,在不開啟o2優化的情況下,洛谷模板題最大資料只需約80ms,而上文的dinic需要約900ms。

下面附上**:

#include

#include

#include

#include

using namespace std;

const int maxn=1e4+10;

const int maxm=2e5+10;

int flow[maxm],gap[maxn],dis[maxn],to[maxm],beg[maxm],nex[maxm];

int e=1,n,m,s,t;

void add(int x,int y,int z)

int isap(int x,int f)

if(!(--gap[dis[x]]))dis[s]=n;

gap[++dis[x]]++;

return f-res;

}int main()

int maxflow=0;

for(gap[0]=n;dis[s]這類問題在最大流問題的基礎上加上了乙個費用的引數,要求在流量最大的基礎上,費用最少。求出此時的流量與費用。

解決這類問題,一般採用ek與spfa相結合的演算法。

該演算法的主要思路,是在ek增廣路演算法的基礎上,使用spfa尋找費用最少的路徑,其餘基本與ek演算法相同。

下面附上**:

#include

#include

#include

#include

#include

using namespace std;

const int maxn=5e4+10;

const int inf=1e+9;

int to[maxn],nex[maxn],beg[maxn],c[maxn],w[maxn],pre[maxn],dis[maxn],vis[maxn],q[maxn<<3];

int n,e=1,m,s,t,maxflow;

inline int read()

void add(register int x,register int y,register int flow,register int cost)

int spfa()}}

}return !(dis[t]==inf);

}int mcmf()

maxflow+=d;

}return cost;

}int main()

int mincost=mcmf();

printf("%d %d\n",maxflow,mincost);

return 0;

}

網路流總結

今天學的網路流,總的感覺來說稍難,不管是理解還是什麼,但是理解了後,就變得簡單許多。ford fulkerson演算法 是來求最大流量問題,從源點出發,到匯點,到底能多少能流入匯點。演算法 1 從源點出發,找相鄰邊,如果相鄰邊未被找過並且還可以流入流量就dfs。2 更新流入的邊。3 重複操作,直到沒...

網路流總結

今天做了一天的網路流,也發現了很多有趣 有毒 的建圖方法,也算是收穫很多了,這裡就做個總結吧。網路流跑的方法大家都會我就不說了,題考察的重點也就是建圖。建圖就涉及到2個方面 1.建點。建點其實就是網路流的難點了,一般點弄好了邊也容易了。建點的困難就在於有時要拆點,我總結了一下拆點主要是這幾個作用 a...

網路流總結

1.hdu1532 給網路圖,求1 n的最大流.注意邊數 2 2.hdu3572 經典建圖模型,有些東西能轉換為容量考慮 網路流演算法.dinic學了乙個多路增廣優化,能少一次遞迴的時間 1.hdu1533 建圖方式,假設有cntm個人,cnth個房子,分別對應編號 1,cntm cntm 1,cn...