1. 程式人生 > >網絡最大流入門

網絡最大流入門

找到 最大 讀者 在外 機會 反向 分開 dinic font

前言

網絡最大流是網絡流中最基礎也是最重要的部分,後邊的許多模型也都是由最大流問題引申而來的

最大流

在研究這個問題之前,讓我們先來學習一下前置知識

以下面這張圖為例

技術分享圖片

可行流

設$f(u,v)$表示邊$(u,v)$的當前容量上限

設$c(u,v)$表示邊$(u,v)$的最大容量上限

如果網絡流圖中的流量滿足

  • 源點$S$:流出量$=$流量總量
  • 匯點$T$:流入量$=$流量總量
  • 任意邊$(u,v)$:$0<=f(u,v)<=c(u,v)$

則稱該流為一個可行流

最大流

定義:在所有可行流中流量最大的流

那麽我們如何求解這個東西呢?

技術分享圖片

很顯然的一種思路就是找到整個網絡中的容量上限最小的邊

增廣(就是加流量)這條路徑,不斷的重復

暫且不說這麽做時間復雜度如何

我們先考慮一下它的正確性。

這麽做貌似很有道理,

但是!

以上圖為例,如只是無腦增廣的話,很可能對SABT這條邊進行增廣,而增廣完這條邊後,就再也沒有可以增廣的路徑了,求出的最大流為$3$,下圖為增廣後的網絡流圖

技術分享圖片

很顯然,這麽做是錯的,因為我們可以分別增廣$SAT$,$SBT$這兩條路徑,得到的流量為$6$

那怎麽解決這個問題呢?

我們需要引入一個非常重要的概念——反向邊

例如,對於$SA$這條容量為$3$的邊,我們可以認為存在一條容量為$0$的邊$AS$與之對應,對於$SA$進行增廣,即減小它的容量上限,相當於增大$AS$的容量上限

也就是說,我們允許從$SA$流出的流量倒流回去,給它一個悔改的機會

這樣,對於上圖而言,我們可以借助反向邊來更改自己的錯誤操作,建立反向邊後的圖如下圖所示

技術分享圖片

這樣我們便又有了一條新的增廣路$SBAT$,對這條路徑進行增廣後我們便可以得到網絡最大流為$5$

考慮一下,為什麽這樣是對的?

原因很簡單,造成我們剛開始做出錯誤決策的邊為$AB$,最大流本不應經過這裏,但是我們卻無腦的經過了這裏

因為反向邊$BA$的存在,我們又把從$A$流向$B$的流量給退了回去。這就相當於沒有經過$AB$這條邊

(本節以下內容讀者可以直接略過,屬於本蒟蒻瞎扯,可能把讀者帶到溝裏面,目前已有一人受害)

反向弧到這裏本就應該結束了,但是本蒟蒻在學習的過程中一直有個問題不明白

為什麽加反向弧是對的?

如果不考慮反向弧,我們選擇的路徑為$SAT$,$SBT$,但是加了反向弧之後我們的路徑貌似不是這麽選的啊。。

尤其是$AT$這條邊的流量,本應該是從$SA$流過來,但實際是從$SB$流過來。

這樣為什麽是對的呢?

這個問題我思考了很長時間,最終得出了一個很不靠譜的結論

因為經過$AB$這條邊的流量為$SA,AB,BT$的最小值,然後xjb分情況討論一下,%……&*()()*&……%¥)(大概要分個一二十種情況吧,然後發現都是對的,其實就是各邊之間的流量等效替代問題。。。)

看到這兒的同學,恭喜你們被帶到坑裏啦O(∩_∩)O哈哈~

實現

我目前見過的最大流算法有以下幾種

EK(最簡單,很慢)

Dinic(最常見,性能良好)

ISAP(也比較常見,性能很好)

最高標號預流推進(HLPP) (沒學過。。)

前置重貼標簽(什麽鬼。。。)

在書上看到過據說可以使用動態樹優化最大流算法,但是把百度翻遍了也沒找到。。。

由於想講的詳細一些,所以想了一下把每個算法分開講吧,我會盡快更新噠:grinning:

(最近這幾天可能不太好辦了,因為博主在外面學(bei)習(nue),只有晚上才能更博客)

網絡最大流入門