網路流練習筆記

Biadocy發表於2021-03-05

一些常用的套路:

  • 必須完成的一些目標,可以考慮搞進流量中,因為跑最大流的話肯定會流滿,也就相當於強制地完成了那些目標。
  • 拆點。然後可以通過兩點之間連某個容量的邊來限制該點取到的次數。
  • 建立超級源點、匯點。幾乎在每道題中都會用到,不光方便計算,還可以通過連邊的方式對某些狀態進行操作。

P1251 餐巾計劃問題

發現每天開始和結束時的狀態是不一樣的,考慮拆點。

接著怎麼辦?模擬餐巾的路線嗎?

假如從白天向晚上連一條邊表示餐巾由乾淨變為髒的話,會發現根本無法處理每天的需求量。

那反正只要是乾淨的就行了,咋來的我們不管,那就直接從超級源點流過來嘛。然後就可以讓餐巾流到超級匯點來完成需求啦!

具體分以下幾種:

  • 由超級源點向每天晚上連一條容量為當日需求,費用為 \(0\) 的邊。表示晚上獲得髒餐巾。
  • 由每天早上向超級匯點連一條容量為當日需求,費用為 \(0\) 的邊。表示白天需要新餐巾。
  • 由每天晚上向次日晚上連一條容量為 \(\infty\),費用為 \(0\) 的邊。表示餐巾不洗留到下一天。
  • 由每天晚上向現在送去快洗能洗好的那天早上連一條容量為 \(\infty\),費用為快洗費用的邊。表示送去快洗。
  • 由每天晚上向現在送去慢洗能洗好的那天早上連一條容量為 \(\infty\),費用為慢洗費用的邊。表示送去慢洗。
  • 由超級源點向每天早上連一條容量為 \(\infty\),費用為購買新餐巾費用的邊。表示購買新餐巾。

然後跑最小費用最大流。

值得注意的是,第三點處於貪心的考慮,肯定會直接洗掉。但我們發現設計的方案中並沒有設定這樣一個庫存餐巾,所以就得通過這一步來使得餐巾能夠在必須洗的那天晚上剛好洗掉,從而達到和提前洗完一樣的效果。所以如果某天晚上就算送去快洗也洗不完了,前一天晚上的這條邊可以不連。

P4015 運輸問題

亂翻網路流二十四題時有幸看到這個帖子

故在此說明一點:最長路徑問題是 NP-HARD 的原因是可能存在正權圈,這種情況下要求最長簡單路徑。類似地,存在負權圈的最短簡單路徑也是 NP-HARD 的。詳情可以看這個回答

每個倉庫向每個零售商店連容量為 \(\infty\),給定費用的邊。再從超級源點向每個倉庫連容量為給定數量,費用為 \(0\) 的邊;從每個零售商店向超級源點連容量為給定數量,費用為 \(0\) 的邊,最後跑最大費用最大流。直接將權值取反然後再跑一遍最小費用最大流即可,記得跑完一遍後記得重置每條邊當前流量。

其實這種簡單題的建模不難,對著題意模擬,把每種可能的情況考慮進去就行了。

P4013 數字梯形問題

如果理解了最上面三條東西可以秒殺。

路徑互不相交說明啥?點不能重複選唄,那就拆點然後兩點之間連容量為 \(1\) 的邊。

路徑僅允許在數字結點處相交說明啥?邊不能重複選,點可以重複選唄,那就兩點之間容量搞成 \(\infty\),從上一層走到下一層的邊容量搞成 \(1\)(容易發現上一種情況這裡設成大於 \(1\) 的都可行)。

路徑隨便相交怎麼辦?除了從超級源點到最上面的 \(m\) 個點容量設為 \(1\) 外其它容量全部 \(\infty\) 唄。

P2765 魔術球問題

神仙題,真的神仙。

依次塞球,如果塞不下了就加一根柱子,直到柱子不夠為止。

那麼具體咋建圖呢?依舊考慮拆點,但拆點的作用有所不同,這裡僅僅是為了方便處理,將每個球拆成出球(疊在一個球上面)和入球(一個球疊在它上面)。

從超級源點向每個入球連容量為 \(1\) 的邊,從每個出球向超級匯點連容量為 \(1\) 的邊。再從每對合法的較小的入球向較大的出球連邊。

可以發現,從超級源點到超級匯點最長只存在長度為 \(3\) 的正向路徑!舉個例子:\(S\to in_1\to out_3\to T\)

但這樣恰好代表了一個球的堆疊!接下來:\(S\to in_3\to out_6\)

這樣就堆疊了兩個球!所以就這樣每次新加一個球,如果最大流沒有增加,說明需要一根新的柱子。

接著來考慮第二問:怎麼找方案?

好像把所有路徑擼出來然後重組一下是可行的,但這裡給一種普適性很差的做法(顯然本題流量僅有 \(0\)\(1\))。

考慮一條正向邊,如果它被選了,那麼流量一定為 \(1\)。DFS 下去,遇到這樣的邊並且出點還沒有用過,就把流量置為 \(1\) 然後繼續遞迴下去。

從超級匯點到入球都沒有問題,到出球時直接輸出。

至於正確性嘛,流量為 \(1\) 的邊肯定是流滿的嘛,那還能咋流呢?不可能出現兩條同時流滿的邊嘛。

P2774 方格取數問題

黑白染色,由相鄰的黑點向白點連容量為 \(\infty\) 的邊。

黑點接到超級源點上,白點接到超級匯點上,權值為對應的數。

想要合法,無非就是一些點不選。顯然中間的邊是不會去刪的,只會刪兩邊的邊。求出最小割(不連通說明合法)然後拿總權值減一下就好了。

相關文章