第26章 最大流(正在修改)

來源:互聯網
上載者:User
一、綜述1.定義

定義1:流網路

定義2:殘留容量

定義3:增廣路徑

已知一個網路流G=(V,E)和流f,增廣路徑p為殘留網路G|f中從s到t的一條簡單路徑

能夠沿一條增廣路徑p的每條邊傳輸的網路流的最大量為p的殘留容量,由下式定義:

c|f(p) = min{c|f(u,v) : (u,v)在p上}

定義4:割、淨流、容量、最小割

淨流和容量的區別:

 穿過(S,T)的淨流由雙向的正網路流組成;在加上從S到T的正網路流的同時,減去從T到S的正網路流。

割(S,T)的容量僅由從S到T的連計算而得。從T到S的邊在計算c(S,T)時是不算在內的。

2.性質

3.定理

定理1:

定理2:

定理3:

定理4:

定理5:

定理6:

對一個網路流G中任意流f來說,其值的上介面為G的任意割的容量

定理7:

 

二、代碼版本一:最大流,圖用矩陣實現,求增廣路徑用BELLMAN-FORD實現1.Mat_Flow.h
#include <iostream>using namespace std;#define NMAX 210class Mat_Flow{public:int n;//點的個數。其中0是源點,1是匯點int map[NMAX][NMAX];//網路費用int net[NMAX][NMAX];//剩餘網路int path[NMAX];//增廣路徑,path[v]=u說明(u,v)在增廣路徑上int ecost[NMAX];//源點到各點的最短路徑Mat_Flow(int num):n(num){memset(map, 0, sizeof(map));}void AddSingleEdge(int start, int end, int value = 1){map[start][end] = value;}void MakeGraph(int m);bool bellman_ford();int max_flow();};void Mat_Flow::MakeGraph(int m){int start, end, value;while(m--){cin>>start>>end>>value;AddSingleEdge(start, end, value);}}bool Mat_Flow::bellman_ford(){int i, j;memset(path, -1, sizeof(path));fill(ecost, ecost+NMAX, INT_MAX);ecost[0] = 0;bool flag = true;while(flag){flag = false;for(i = 0; i <= n; i++){if(ecost[i] == INT_MAX)continue;for(j = 0; j <= n; j++){if(net[i][j] > 0 && ecost[i] + 1 < ecost[j]){flag = true;ecost[j] = ecost[i] + 1;path[j] = i;}}}}return ecost[n] != INT_MAX;}int Mat_Flow::max_flow(){int i, j;//初始時,剩餘網路即為整個網路for(i = 0; i <= n; i++){for(j = 0; j <= n; j++)net[i][j] = map[i][j];}int maxflow = 0;//while there exists a path p from s to t int the residual network G1//從剩餘網路中找到一條增廣路徑,增廣路徑存在在path中while(bellman_ford()){//do c|f(p) <- min {c|f(u,v):(u,v) is in p}//計算增廣路徑上的淨流int v = n, cfp = INT_MAX, u;while(v != 0){//path儲存的是增廣路徑,path[v]=u說明(u,v)在增廣路徑上u = path[v];cfp = min(cfp, net[u][v]);v = u;}//更新最大流的大小maxflow += cfp;//更新剩餘網路//for each edge(u,v) in pv = n;while(v != 0){u = path[v];//f[u,v] <- f[u,v] + cfpnet[u][v] -= cfp;net[v][u] += cfp;//f[v,u] <- -f[u,v]v = u;}}return maxflow;}
2.main.cpp
#include "Mat_flow.h"/*5 100 1 160 2 131 3 121 2 102 1 43 2 92 4 143 5 204 3 74 5 4*/int main(){int n, m;while(cin>>n>>m){Mat_Flow *G = new Mat_Flow(n);G->MakeGraph(m);cout<<G->max_flow()<<endl;delete G;}return 0;}
3.測試資料

《演算法導論》P405圖26-5

 4.運行結果

版本2:矩陣+HLPP(高度標號預流推進演算法)1."Mat_HLPP_Flow.h"

http://my.csdn.net/my/code/detail/50632

2.main.cpp
#include "Mat_HLPP_Flow.h"/*5 100 1 160 2 131 3 121 2 102 1 43 2 92 4 143 5 204 3 74 5 4*/int main(){int n, m;while(cin>>n>>m){Mat_HLPP_Flow *G = new Mat_HLPP_Flow(n);G->MakeGraph(m);cout<<G->high_label_preflow_push()<<endl;delete G;}return 0;}
3.測試資料與測試結果

同上

 

三、練習26.1 網路流

26.1-1

定義1:如果(u,v)不屬於E,c(u,v)=0性質1:f(u,v) <= c(u,v)====> 如果(u,v)不屬於E,f(u,v) = 0。反向邊同理

26.1-2
性質2,反對稱性
26.1-3
待解決
26.1-4

26.1-5

(1)f(X,Y)=-f(V-X,Y)X:t   Y:v3,v4(2)f(X,Y)!=-f(V-X,Y)X:v3,v4  Y:v1,v2

26.1-6
必定滿足“反對稱性”和“流守恒性”,可能違反“容量限制”
26.1-7

由26.1-6知,af1+(1-a)f2滿足“反對稱性”和“流守恒性”。因為f1和f2滿足“容量限制”,因此af1+(1-a)f2滿足“容量限制”所以af1+(1-a)f2也是流

26.1-8
待解決
26.1-9

將地圖轉換為一個有向圖:(1)每個角落作為一個頂點(2)若一個角落到另一個角落有路,則構成有向圖的邊。(3)每條路構成正向和反向兩條邊,容量都是1計算該有向圖的最大流,若最大流大於或等於2,則“可以”

 

26.2Ford-Fulkerson方法
26.2-1淨流:19容量:3126.2-2圖26.2-3最大流的最小割是23第二第和第三條抵消了26.2-4c|f(u,v) + c|f(v,u) =c(u,v) - f(u,v) + c(v,u) - f(v,u) =c(u,v) + c(v,u) 26.2-5 26.2-6 本來就是最大流問題,要轉換? 22.2-7 後面還沒做

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.