1. 程式人生 > >有上下界網路流建模方法

有上下界網路流建模方法

假設上界為 rr, 下界為 ll

無源匯可行流(迴圈流)

法一:

建立源點 ss 和匯點 tt , 對於圖中每條邊 <u,v><u, v> ,拆成如下三條:

  • $<s,v> $ ,容量為 ll
  • $<u,t> $ ,容量為 ll
  • &lt;u,v&gt;&lt;u, v&gt; ,容量為 rlr - l

其中前兩條弧一般稱為附加弧。

然後對圖跑從 sstt 的最大流,如果所有附加弧都滿流,則有可行流。這時,每條非附加弧的流量加上它的容量下界,就是原圖中這條弧應該有的流量。

法二:

建立源點 ss 和匯點 tt ,對於每條邊建立 &lt;u,v&gt;&lt;u,v&gt; 容量為 rlr-l 的邊。此外,對於圖中每個點,令 $節點所有入流下界和節點所有出流下界和d[i] = \sum i節點所有入流下界和 - \sum i節點所有出流下界和 $ 。求 dd 陣列:若有一條 &lt;u,v,L,R&gt;&lt;u,v,L,R&gt; 的邊,令 d[u]=L,d[v]+=Ld[u] -= L, d[v] += L

[v]+=L 即可。

d[i]&gt;0d[i] &gt; 0, 建立 &lt;s,i&gt;&lt;s,i&gt; 容量為 d[i]d[i] 的邊。

d[i]&lt;0d[i] &lt; 0 ,建立 &lt;i,t&gt;&lt;i,t&gt; 容量為 d[i]-d[i] 的邊。

然後跑 sstt 的最大流,若附加邊全部滿流,即 maxflow=d[i]&gt;0maxflow = \sum d[i] &gt;0

之和,存在可行流。每條邊流量同法一。

有源匯可行流

從匯點 tt 建立一條流向源點 ss 的邊,上界為 infinf 下界為 00 ,就轉化成了無源匯可行流。然後按照無源匯的判定方法建圖即可,需要建立一個超級源點 SSSS 和超級匯點 TTTT .求原圖中每條邊對應的實際流量的方法,同無源匯可行流,只是忽略掉弧 &lt;t,s&gt;&lt;t,s&gt; 就好。而且這時候弧 &lt;t,s&gt;&lt;t,s&gt; 的流量就是原圖的總流量。

有源匯最大流

判斷有解方法如上說述。而且一定要先判是否有解

如果存在可行流,那麼在執行過有源匯可行流的圖上(就是已經存在流量的那張圖,流量不要清零),跑一遍從 sstt 的最大流(這裡的 sstt 是原圖的源和匯,不是附加超級源和附加超級匯),就是原圖的最大流。

有源匯最小流

同上方法判斷是否有解。求最小兩種方法:

  1. 首先按照有源匯可行流的方法建模,但是不要建立&lt;t,s&gt;&lt;t,s&gt;這條弧

    然後在這個圖上,跑從附加源 ssss 到附加匯 tttt 的最大流。

    這時候再新增弧 &lt;t,s&gt;&lt;t,s&gt;,下界為 00,上界為 infinf

    在現在的這張圖上,從 sssstttt 的最大流,就是原圖的最小流。

    理解方法:

    我們前面提到過,有源匯可行流的流量只是對應一組可行流,並不是最大或者最小流。

    並且在跑完有源匯可行流之後,弧&lt;t,s&gt;&lt;t,s&gt;的流量就是原圖的流量。

    從這個角度入手,我們想讓弧&lt;t,s&gt;&lt;t,s&gt;的流量儘量小,就要儘量多的消耗掉那些“本來不需要經過&lt;t,s&gt;&lt;t,s&gt;”的流量。

    於是我們在新增&lt;t,s&gt;&lt;t,s&gt;之前,跑一遍從 sssstttt 的最大流,就能儘量多的消耗那些流量了。

  2. 把最小流的初始值設為 TTSS 這條邊的流量,把 SSSS 連出去的邊清掉,把 TTSS 的邊刪掉,再在殘量網路上跑一次 TTSS 的最大流,初始最小流減去這次的最大流就是答案。