幾個關於最大流最小割的經典模型
\(\color{red}{p.s.因為是給自己記錄一下防止忘記的小記,所以證明大多是感性理解。}\)
一、最大流
1、二分圖匹配
(1)只統計邊數的二分圖最大匹配
顯然是可以用匈牙利演算法的,但是因為匈牙利演算法本質可以看做EK,最大流EK還是挺慢的,所以可以用dinic跑
從源點向左部的每個點連上一條容量為1的邊,從右部每個點也向匯點連上一條容量為1的邊,中間的邊保持不變並設定容量為1。
證明顯然,每個點只會選一次每條邊也最多選一次。
(2)每個點可以用多次的二分圖最大匹配
相似的,但是將源點和匯點連的邊改成該邊另一個點能用的最大次數,證明類似。
tips:沒有奇環的圖是必然二分圖。
2、最小路徑覆蓋
求最小的頂點不相交的路徑條數使得所有點被覆蓋。
首先把每個點拆成入點和出點,按照原圖連邊,容量為1,並且從源點向每個入點連一條容量為1的邊,從每個出點向匯點連一條容量為1的邊,答案就是原圖總點數減最大流。
證明:可以發現這個答案的實質就是點數減二分圖最大匹配。很容易發現每條路徑上點數都會比邊數多一,那麼我們用點數減去邊數就是路徑數量,減去最大匹配就是最小路徑數量。
3、拆點
算小技巧吧,有兩種情況:
1、如果題目裡面對某個點的使用次數有限制,但是相鄰的邊不能很好地約束點的限制,那麼可以把這個點拆成入點和出點,在入點和出點之間連容量為次數的邊。
2、有億些這條邊的限制與上條邊的限制題目可以強行
4、上下界問題(雖然題目不多,但是最煩了)
(1) 無源匯上下界可行流
你會發現,一個很簡單的想法,那就是把容量直接設成上界減下界,但如果這樣如果直接最大流的話,流量是不守恆的,會出大問題,那為了平衡流量,我們可以把每個下界減在上一個點上,同時加在下一個點上,你會發現這樣總流量是不變的,但是轉移的時候就相當於是補上來了下界,我們只需要最後看一下每個點經過這些加減操作以後總值是多少,如果是正的就從超級源點向這個點連一條容量為總值的邊,如果是負的就從這個點向超級匯點連一條容量為總值相反數的邊,然後如果從超級源點連出來的那些邊都滿流了就說明你的流量守恆了,所以就有可行流,否則就沒有。
(2) 有源匯上下界最大流
首先將它轉化為無源匯的,從原來的匯點像原來的源點連一條容量為正無窮的邊來使得流量守恆,然後按照無源匯的可以跑出來一個可行流。然後就是感性理解了:你建的從原來匯點像原來源點連的那條邊的流量顯然就是平衡的整個網路的流量,所以這個流量就是這個可行流的流量,記為f。你會發現原網路裡會有一些沒有榨乾的流存在,那你就把從原來匯點向原來源點的的邊刪掉再跑一邊從原來源點向原來匯點最大流,然後把答案加上f就是最終的最大流答案了(但是這個證明似乎是不嚴謹的,因為源點匯點改變了,嚴謹證明還要抵消啥亂七八糟的,可以參考OI wiki)。
(3) 有源匯上下界最小流
前面可行流的步驟顯然是與有源匯上下界最大流一致的,然後跑一邊從原來匯點像原來源點的最大流,用f減掉這個最大流就是答案(證明顯然)。
5、多源匯
從超級源點向每個源點連一條容量為 \(+\infty\) 的邊,從每個匯點向超級匯點連一條容量為 \(+\infty\) 的邊,中間該怎麼建怎麼建。
6、關建邊(雖然我也不知道為啥,但是好像的確就是這個建)
關建邊:擴大一條邊容量以後整個網路最大流都會變大。
一條邊是關建邊一定得滿足兩個條件:
(1)流量滿了,因為如果沒滿的話那擴大也沒用;
(2)它所在的某條從源點到匯點路徑上正好是它卡住了最大流。
第一個很容易判斷,殘量網路是0就說明滿了。第二個就說明它的兩個端點可以分別從源點和匯點沿殘量網路中的非零邊搜到,那做兩遍dfs分別標記源點和匯點分別可以搜到的點然後判斷就行了。
7、退流
刪掉一條 \(u\) 到 \(v\) 的邊可以先從源點到 \(u\) 跑一邊最大流,從匯點到 \(v\) 跑一邊最大流,減去後將邊(u,v)的容量以及殘量網路容量都設為0就做完了。
證明:就是相當於把原來網路裡的源點到 \(u\) 和匯點到 \(v\) 的流量利用流網路的反悔機制給它倒回去了。
8、最大流結合簡單線性DP(難的不會)
一般是正常跑DP後按照轉移方式從上一步向這一步連邊,然後按題目要求來就行了。
9、最大流判定最小(大)答案
一般來說可以二分解決,但如果只是每次加上一個或者幾個點可以直接列舉跑最大流,因為殘量網路是非常優秀的(確信)。
二、最小割
1、最小割輸出方案
從源點沿著殘量網路容量非0的邊dfs,能搜到的在源點集合裡,不能搜到的在匯點集合裡,兩個集合中間的邊為割。
2、平面圖最小割/最大流轉最短路
平面圖最小割/最大流可以轉化為對偶圖的最短路。
證明:顯然對偶圖的每一條邊就可以對應原平面圖的每一條割邊,那麼最短路就是最小割。
3、最大權閉合子圖
閉合子圖:子圖裡每個點都沒有指向子圖外點的邊。
我們從源點向點權為正的點連一條容量為點權的邊,從匯點向點權為負的點連一條容量為點權相反數的邊(點權為零因為沒有任何貢獻放在哪裡都沒有影響,下面的零同理不考慮),內部邊保留且容量為 \(+\infty\),答案就是正點權和減去該圖最小割。
證明:首先證明最小割肯定不包含容量為 \(+\infty\) 的邊(我們稱之為簡單割),這個是很顯然的,因為最小割等於最大流,而該圖是存在關建邊的,也就是流量不可能為 \(+\infty\),所以最小割也一定不可能含有容量為 \(+\infty\) 的邊。我們先將所有點權為正的點都與源點放在同一個集合 \(s\) 中,點權為負的點都與匯點放在同一個集合 \(t\) 中。
那麼我們現在為了選出一個閉合子圖,有兩種選擇:
(1) 放棄一個正權點,即把一個正權點丟進 \(t\) 中,那麼這個點點權為長度的邊就被割了;
(2) 選上一個負權點,同理。那麼我們得到的兩個集合一定沒有指向外面的邊(因為簡單割肯定沒有長度為 \(+\infty\) 的邊)。
所以答案就等於正點權和減最小割。
輸出方案:顯然就是源點沿著殘量網路非0邊可以dfs到的點。
4、最小權覆蓋集
覆蓋集:一個點集,使得無向圖中每條邊的兩個頂點至少有一個點在該點集中。
任意圖的最小權覆蓋集是一個NPC問題,我們在這裡考慮二分圖的最小權覆蓋集。考慮從源點向左部每個點連一條容量為點權的邊,右部每一個點向匯點連一條容量為點權的邊,中間的邊保留不變,容量為 \(+\infty\),答案就是該圖最小割。
證明:同最大權閉合子圖,可以證明最小割必然是簡單割,也就是說我們只會選到左邊或者右邊的邊,並且每條中間的邊會且僅會對應一條左邊或者右邊的邊,也就是左邊或者右邊的點權,所以最小權覆蓋集就等於最小割。
tips:以上是點權全正的情況,有負權可以先把負權點都選上,刪掉這些點連線的邊,然後再跑以上演算法。
輸出方案:源點沿著殘量網路非0邊可以dfs一邊,統計左端點訪問過,右端點未訪問過的邊,答案就是這些邊中非源匯的點。
5、最大權獨立集
獨立集:一個點集,使得任意兩個點沒有邊直接相連。
答案為總點權建最小權覆蓋集(即最小權覆蓋集同樣建圖方法下的最小割)。
證明:即證明覆蓋集的補集一定是獨立集。我們考慮反證法,如果覆蓋集的補集不是獨立集,那麼補集裡一定有邊連線兩個點,而這兩個點又都沒有被選在覆蓋集裡,與覆蓋集定義矛盾,所以覆蓋集補集一定是獨立集。同樣的,如果獨立集補集不是覆蓋集,那麼一定會有至少一條邊沒有被其補集覆蓋,那麼它只能兩個端點都在獨立集內,與獨立集定義矛盾。所以獨立集與覆蓋集互為補集且一一對應,得證。
tips:以上是點權全正的情況,有負權同最小權覆蓋集。
輸出方案:最小權覆蓋集的補集。