網絡流(五)有上下限的最大流


傳送門:

網絡流(一)基礎知識篇

網絡流(二)最大流的增廣路算法

網絡流(三)最大流最小割定理

網絡流(四)dinic算法

網絡流(五)有上下限的最大流

網絡流(六)最小費用最大流問題

轉自:https://blog.csdn.net/water_glass/article/details/6823741

問題模型:

給定一個加權的有向圖,滿足:

 

(1)容量限制條件:

              

(2)流量平衡條件:

             

 

(2)中的即除了源匯外,所有點都滿足流量平衡條件,則稱G為有源匯網絡;否則,即不存在源匯,所有點都滿足流量平衡條件,則稱G為無源匯網絡。

將這類問題由易到難一一解決:

問題[1] 求無源匯的網絡有上下界的可行流

由於下界是一條弧上的流必需要滿足的確定值。下面引入必要弧的概念:必要弧是一定流要滿的弧。必要弧的構造,將容量下界的限制分離開了,從而構造了一個沒有下界的網絡G’:

1. 將原弧(u,v)分離出一條必要弧:。(紅色表示)

2. 原弧:

由於必要弧的有一定要滿的限制,將必要弧“拉”出來集中考慮:

添加附加源x, 附加匯y。想像一條不限上界的(y, x),用必要弧將它們“串”起來,即對於有向必要弧(u, v),添加(u, y),(x, v),容量為必要弧容量。這樣就建立了一個等價的網絡。

一個無源匯網絡的可行流的方案一定是必要弧是滿的。若去掉(y, x)后,附加源x到附加匯y的最大流,能使得x的出弧或者y的入弧都滿,充要於原圖有可行流。

算法:

1. 按上述方法構造新網絡(分離必要弧,附加源匯)

2. 求附加源x到附加匯y的最大流

3. 若x的出弧或y的入弧都滿,則有解,將必要弧合並回原圖;否則,無解。

問題[2] 求有源匯的網絡有上下界的可行流

加入邊(t, s),下界為0(保證不會連上附加源匯x, y),不限上界,將問題[2]轉化為問題[1]來求解。

調用dinic算法

 1 bool lowbound_flow(int n, int source, int sink)
 2 {
 3     init(n + 2);
 4     vector<int>tot_in(n + 1), tot_out(n + 1);
 5     for(int i = 0; i < (int)u.size(); i++)
 6     {
 7         if(U[i] < L[i])return false;
 8         tot_in[v[i]] += L[i];
 9         tot_out[u[i]] += L[i];
10         addedge(u[i], v[i], U[i] - L[i]);
11     }
12     addedge(sink, source, 100000000);
13     int super_source = n + 1;
14     int super_sink = n + 2;
15     for(int i = 0; i < n; i++)
16     {
17         addedge(super_source, i, tot_in[i]);
18         addedge(i, super_sink, tot_out[i]);
19     }
20     int ans = Maxflow(super_source, super_sink);
21     //cout<<ans<<endl;
22     for(int i = 0; i < G[super_source].size(); i++)
23     {
24         edge& tmp = e[G[super_source][i]];
25         if(tmp.f != tmp.c)return false;//判斷是否滿流 不滿流則錯誤
26     }
27     return true;
28 }

 

問題[3]求有源匯的網絡有上下界的最大流

算法:

1. 先轉化為問題[2]來求解一個可行流。若可行無解,則退出。由於必要弧是分離出來的,所以就可以把必要弧(附加源匯及其臨邊)及其上的流,暫時刪去。再將(T,S)刪去,恢復源匯。

2. 再次,從S到T找增廣軌,求最大流。

3. 最后將暫時刪去的下界信息恢復,合並到當前圖中。輸出解。

這樣既不破壞下界(分離出來)也不超出上界(第2步滿足容量限制),問題解決。

問題[4]求有源匯的網絡有上下界的最小流

算法:

1. 同問題[3]。

2. 從T到S找增廣軌,不斷反着改進。

3. 同問題[3]。

問題[3]與問題[4]的另一種簡易求法:

注意問題[2]中,構造出的(t, s),上下界幾乎沒什么限制。下面看看它的性質:

定理:如果從s到t有一個流量為a的可行流f,那么從t到s連一條弧(t, s),其流量下界b(t, s) = a,則這個圖一定有一個無源匯的可行流:除了弧(t, s)的容量為a外,其余邊的容量與f相同。

證明:如果從s到t的最大流量為amax,那么從t到s連一條下界b(t, s) = a’ > amax的弧(t, s),則從在這個改造后的圖中一定沒有無源匯的可行流:否則將這個可行流中的弧(t, s)除去,就得到了原圖中s到t的流量為a’的流,大於最大流量amax,產生矛盾。

可以二分枚舉這個參數a,即下界b(t, s),每次用問題[1]判斷是否有可行流。這樣就可以求出最大流。

同理,問題[4]要求最小流,只要二分枚舉上界c(t, s)即可。

因為朴素的預流推進算法O(N3),總復雜度為O(N3 log2流量) 。

思路:

無源匯 (附加源匯+最大解決)

有源匯 (附加(T,S)->無源匯)

 

求有源匯的網絡有上下界的最大流:(s-u v-t之間的路省略了)

(1)對於每條邊,拉出一條必要弧(下限)

 


(2)去除T到S的邊,然后求S-T的最大流F0

 

(3)如果S-T的最大流使得所有的S出邊流量滿,T的入邊流量滿,問題有解,否則無解

兩者只要有一者是滿的,另一個一定是滿的,因為總的出流量=總的入流量

有解的時候F0 = 所有下界之和

(4)如果有解,在原來S-T的最大流網絡的基礎上,刪去所有與S和T相連的邊,並且剩下的每條邊的流量都加上下限值,在此基礎上繼續擴充找增廣路,最終的得到的答案就是最大流

挑戰中介紹了第4步另一種方法,直接在S->s連+INF的邊,t->T連+INF的邊,再求一遍S-T的最大流F,那么原圖最大流為F-F0(也就是F-下界之和)

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM