我退坑很久了,這篇文章不是因為刷oj而寫的總結,畢竟菜雞老年人, 23333
之前我學網路流看的是演算法書和別人的部落格然後就開始套板子,而這次因為考試不得已把課本上的定理都看了一遍,瞬間對最大流演算法更加清楚了。
在學習網路流演算法前要了解的一些知識。
1.對於乙個有向的網路$g=(n, a, c)$,其中的$c_$表示弧$(i,j)\in a$的容量,並設$s,t$為發點和收點,令
$$x_=通過弧(i,j)的流量
$$2.對於乙個滿足流量限制的流量稱之為可行流,其中限制條件為
(1)守恆方程(對於非收發點,流入流量等於流出流量)
$$\sum_j x_-\sum_j x_=\left\
+v,\,\,\, i =s \\
0,\,\,\, i \neq s,t \\
-v,\,\,\, i =t
\end
\right.
$$(2)$0\leq x_ \leq c_$
3.設p是g中從s到t的無向路,若弧$(i,j)$的方向是從s到t,那麼稱之為前向弧,否則為後向弧。
4.如果對於g的乙個無向路p,有前向弧$(i,j)$,$x_ < c_$。有後向弧$(i,j)$,$x_>0$則稱p為增廣路。
以ford-fulkerson演算法為例進行介紹
最大流演算法的思想是找一條增廣路,對其進行增加流量值,使其變成乙個新的可行流,直到找不到增廣路。
可是為什麼是增廣路呢?
那是因為增廣路有且僅有以下兩種情況,均可以增加流量
1.增廣路上都是前向弧。
圖中黑色數字表示邊容量,紅色數字表示現有流量。下圖同。
對於這種情況,直接對每個邊上進行流量的增加就好了。
2.增廣路上有後向弧。
這種情況才是網路流中的重中之重。
對於前向弧進行流量的增加乙個單位,對於後向弧進行流量的減少乙個單位。
為什麼要這麼做呢?觀察弧$(5,4)$,如果我們把這個弧上的流量退掉,那麼退掉的這部分流量就可以增加到弧$(5,6)$上,保持節點5的流量守恆,因為節點5的退流,節點4流入的流量就減少乙個單位,但是我們把節點4前面的前向弧都增加了乙個單位,因此同樣保證了節點4的守恆,同時增加了流量。
所以可以利用後向弧的這個特點對增廣路進行流量的增加。
這樣就得到了增廣路的所有情況均可以對流量進行增加。
下面為網路流的兩個主要定理:
1.增廣路定理:乙個可行流是最大流當且僅當不存在關於它從s到t的增廣路。
證明:首先求出最大流的上界
定義乙個弧割$(s,t)$,其中$s\in s, t\in t$ 【弧割:去掉使得圖強連通的分支嚴格增加的邊的集合,這裡指的是去掉使得圖的點集合n被分成s和t兩個集合】
那麼割$(s,t)$的容量定義為$c(s,t)=\sum_\sum_c_$
因此可知從s到t的流量v不會大於$c(s,t)$,即
$$v\leq c(s,t)
$$然後證明這個這個可行流是最大流
取s為從s可按照增廣路到達的點集合,$t=n-s$,那麼可以得到對於任意的$i\in s$和$j\in t$,有前向弧為滿流狀態,後向弧為0。(因為從i到j已經沒有路可走了,只有這兩個狀態)
因此有$$
v=\sum_\sum_x_=\sum_\sum_c_=c(s,t)
$$由最大流的上界可以保證此時達到最大流。
2.最大流最小割定理:乙個$(s,t)$流的最大值為$(s,t)$割的最小容量。
證明;根據前面的證明可以知道最大流為c(s,t)的下確界,而在推到過程中可以取到,所以該定理成立。
然後所有的理論工作就完成了,剩下的就是對網路進行dfs或bfs直到找不到增廣路為止。
最大流最小割演算法入門理解
最近在看maxflow相關的資料,本文主要介紹下自己對最大流和最小割的理解。最大流本來是網路流方面的演算法,後來在計算機視覺中也得到廣泛的應用,如圖割。我覺得要理解乙個演算法首先要從起源開始,然後再去泛化問題 建立模型,最後才是解決之。本文是以乙個新手的角度去理解演算法。首先從最簡單的開始,先看一幅...
乙個簡單的最大流演算法
資料結構與演算法分析 c語言描述 第九章 圖論演算法 graph裡面增加乙個函式 void setweight double weight,edgenodeptr p 深度搜尋 簡單的最大流 vertex startvex,endvex 起點,終點 graph gr 殘餘圖 graph gf 流圖 ...
最大流EK和Dinic演算法
最樸素的求最大流的演算法。做法 不停的尋找增廣路,直到找不到為止 如下 frosero include include include include define inf 0x3f3f3f3f using namespace std int n,m int cap 202 202 flow 202...