網路流 費用流

2021-09-25 18:45:07 字數 2417 閱讀 5418

網路流有很多種類

其中最大流

有增廣路演算法和預流推進演算法。增廣路演算法就是不斷的新增增廣路。

其中的dinic演算法。

(會稍微提到isap演算法)

poj1273

首先想到dfs一直往後延伸,然後從源點到匯點計算每條路,但是這樣只是單條路的最值,有時可能因為走一條路而間接的認定了除這條路以外的某個路通量為零,導致最後最大流不是最大。

其次想到了bfs往後均勻延伸,然後會發現這樣很浪費時間,因為每次都是各個方向,每個相鄰的節點都拓展延伸。

最終想到了用dfs、bfs結合使用,然後利用了dinic演算法,通過每次利用bfs遍歷一遍看是否存在從源點到匯點的路徑,然後如果存在了就用dfs去深度往前走,此時應該注意在剛才的bfs過程中應該在瀰散的過程中用乙個layer來記錄所有節點的層數,這樣就可以避免在dfs深搜過程中發生往回走的情況,只會一直指引著往匯點的層次走。

然後寫一下isap演算法與dinic演算法的區別:

在bfs標記節點深度的時候,dinic是從源點到匯點標記深度,然後從源點開始dfs;而isap是從匯點到源點標記深度,然後從源點開始dfs。這樣可以減少bfs次數,有時還可減少dfs次數,然後就是在isap在dfs過程中通過對維護層次值來減少dfs次數。(大佬講解)

**注釋很多。

由於有很多容器,如陣列、雙向佇列,然後雙向佇列也有幹不同用處的,儲存節點、儲存dfs的路徑,因此很容易有時候忘記pop的問題導致死遞迴,死迴圈,一直挑不出迴圈。(尤其mac的xcode 死遞迴了竟然不輸出,還以為執行時間有點久,等了一會xcode卡到轉圈整個人都懵了)。大佬可以跳過後面這句話。所以可以在迴圈中寫乙個stop++來控制這個迴圈走多少次,防止跳不出(也要記得刪,因為沒刪wa了兩發)。

**

//

// main.cpp

// 網路流板題_poj1273

//// created by 陳冉飛 on 2019/7/31.

//#include

#include

#include

using namespace std;

#define maxn 1<<29

int stop =0;

int g[

300]

[300];

int layer[

300]

;//用來看每個節點距離源點所在的層數

bool is_vis[

300]

;//用來看每個節點是否被訪問過

int n,m;

//1 為源點 m 為匯點

//bfs的思路看看能不能找到到最後會點的路,如果有路,就返回true ,並在下邊dinic演算法中這個用來做判斷,如果有路,就用dfs通過層數進行遍歷,每次只走層數疊加的路

bool countlayer()

else}}

}return false;

}int

dinic()

// }

// }

// for (i = 1; i <= m; i ++)

// cout// cout<<"dfs counting ans "memset

(is_vis,0,

sizeof

(is_vis));

is_vis[1]

=1;while

(!dq.

empty()

)}//找了一圈,發現沒有這個點,那麼就回溯,把當前這個末尾這個點pop_back()掉,類似於dfs這一層不行,然後把這一層刪掉,返回到上一層

if(i>m)

}else

}//增廣,改圖

//首先要ans加上這一次的得到的路徑所能流過的值

ans +

= min_val;

//然後對路徑上的所有值進行更改。 不是所有節點,因為是增廣,改圖

for(i =

1; i size()

; i++

)//類似dfs中的返回,到達頂值之後,可以通過pop讓佇列中的值返回到min_bg,標記的最小的位置,然後再接著遍歷

while

(!dq.

empty()

&& dq.

back()

!= min_val)}}

}return ans;

}int

main

(int argc,

const

char

* ar**)

cout<<

dinic()

<}return0;

}

費用流:

也有很多種類

這裡是其中的最小費用最大流,也就是最大流的前提下保證費用最小。

模版題

網路流 費用流

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

網路流之費用流

求費用流目前好像只有ek spfa改版,時間複雜度為o n e k 其中k為最大流值。但時間上的期望時間複雜度為 o a e k 其中a為所有頂點進佇列的平均次數,可以證明a一般小於等於2。最小費用最大流 include using namespace std const int inf 0x3f3...

網路流之費用流

發現我真的是比較玄學,寒假主學最大流的時候忘記搞一下費用流了。然後現在來補。其實如果理解了最大流的思想和演算法的話還是很好寫的。畢竟就是把ek的bfs改成spfa 關於費用流的定義,我們在一般的網路流的定義上給每條邊加上乙個邊權,邊權的意義就是流量的單價 也就是每1單位的流經過這條邊,那麼就要邊權的...