模板歸納 網路流及費用流

2021-09-05 10:45:22 字數 2001 閱讀 1112

首先是網路流及最小費用最大流的兩種最基礎演算法

這兩種網路流演算法的思想核心都是尋找增廣路+沿增廣路擴充套件新流

首先是dinic 演算法

使用bfs尋找增廣路,記錄增廣路中節點層數,

而在dfs中沿著層數+1的方向不斷遞推

直到無法再找到新的增廣路為止

**

#include

#include

#include

#include

#include

#include

#include

using namespace std;

#define n 105

#define next nico

int head[n]

,to[n*n*2]

,next[n*n*2]

,dis[n*n*2]

,tot=

1,d[n]

,s=0

,t,n,m;

void

add(

int x,

int y,

int z)

intbfs()

}}return d[t];}

intdfs

(int x,

int v)

}return ans;

}int

dinic()

return ans ;

}

接下來是最小費用最大流

存圖時注意反向邊的費用是正向邊的相反數

同dinic演算法的區別在於一次只有一條增廣路,且這條增廣路是費用最短路

可以使用spfa來尋找增廣路

然而所以我採用了dijkstra

但是dijkstra不能處理負邊權,怎麼辦?

一種方法是每條邊權加上乙個足夠大的數最後再減去

但是有著溢位的風險!

另一種方法

我們採用陣列h[i]表示上一次增廣路時的最短路

w[i][j]表示連線i,j邊的權值

那麼有h[i]+w[i][j]>=h[j]

所以h[i]-h[j]+w[i][j]>=0

記儲存當前最短路的陣列為f[i]

而我們可以證明最後求出的最短路長度即為f[i]-h[i]

最後為了維護h

只需要每個h[i]+=f[i]

**

#include

#include

#include

#include

#include

#include

#define n 5003

#define next nico

using namespace std;

int head[n]

,to[n*20]

,v[n*20]

,cost[n*20]

,from[n]

,flow[n]

,next[n*20]

,f[n]

,path[n]

,tot=

1,h[n]

,n,m;

int sumflow,sumcost;

int s,t;

void

add(

int x,

int y,

int a,

int b)

struct dat

}buf;

intdijkstra()

);while

(!p.

empty()

));}

}}return f[t]

!=inf;

}void

mcmf()

for(

int i =

1; i <= n; i ++)}

}int

main()

mcmf()

;printf

("%d %d"

,sumflow,sumcost)

;}

網路流 費用流模板

中求的是最小費用最大流,求最大費用最大流只需要在設定邊權時設定為原權值的相反數,執行一次最小費用最大流,計算得出最小費用的相反數就是要求的最大費用。u x v x w x c x 分別表示 x 號邊的出發點,到達點,權值和殘量。1 intspfa 29 dis s 0 10 head tail 1 ...

網路流 費用流

這個好像不考 沒事可以騙分 費用流,顧名思義,就是有費用的流,也就是說,給乙個網路流圖中的每條弧增加乙個單位流量費用。一般來說求解的費用流都是最大流最小費用。好像沒什麼好bb的 這裡推薦使用zkw演算法求解最小費用流,看著 理解就行,應該還是很好理解的。zkw演算法在稠密圖上跑得飛快,在稀疏圖上還不...

網路流 費用流

網路流有很多種類 其中最大流 有增廣路演算法和預流推進演算法。增廣路演算法就是不斷的新增增廣路。其中的dinic演算法。會稍微提到isap演算法 poj1273 首先想到dfs一直往後延伸,然後從源點到匯點計算每條路,但是這樣只是單條路的最值,有時可能因為走一條路而間接的認定了除這條路以外的某個路通...