最大網路流

2021-08-04 22:42:00 字數 3201 閱讀 6849

求網路流有很多演算法,這幾天學習了兩種,記錄一下ek演算法。

首先是網路流中的一些定義:

v表示整個圖中的所有結點的集合.

e表示整個圖中所有邊的集合.

g = (v,e) ,表示整個圖.

s表示網路的源點,t表示網路的匯點.

對於每條邊(u,v),有乙個容量c(u,v)   (c(u,v)>=0),如果c(u,v)=0,則表示(u,v)不存在在網路中。相反,如果原網路中不存在邊(u,v),則令c(u,v)=0.

對於每條邊(u,v),有乙個流量f(u,v).

乙個簡單的例子.網路可以被想象成一些輸水的管道.括號內右邊的數字表示管道的容量c,左邊的數字表示這條管道的當前流量f.

網路流的三個性質:

1、容量限制:  f[u,v]<=c[u,v]

2、反對稱性:f[u,v] = - f[v,u]

3、流量平衡:  對於不是源點也不是匯點的任意結點,流入該結點的流量和等於流出該結點的流量和。

只要滿足這三個性質,就是乙個合法的網路流.

最大流問題,就是求在滿足網路流性質的情況下,源點 s 到匯點 t 的最大流量。

求乙個網路流的最大流有很多演算法 這裡首先介紹 增廣路演算法(ek)

學習演算法之前首先看了解這個演算法中涉及到的幾個圖中的定義:

**殘量網路

為了更方便演算法的實現,一般根據原網路定義乙個殘量網路。其中r(u,v)為殘量網路的容量。

r(u,v) = c(u,v) – f(u,v)

通俗地講:就是對於某一條邊(也稱弧),還能再有多少流量經過。

gf殘量網路,ef

表示殘量網路的邊集.

這是上面圖的乙個殘量網路。殘量網路(如果網路中一條邊的容量為0,則認為這條邊不在殘量網路中。

r(s,v1)=0,所以就不畫出來了。另外舉個例子:r(v1,s) = c(v1,s) – f(v1,s) = 0 – (-f(s,v1)) = f(s,v1) = 4.

其中像(v1,s)這樣的邊稱為後向弧,它表示從v1到s還可以增加4單位的流量。

但是從v1到s不是和原網路中的弧的方向相反嗎?顯然「從v1到s還可以增加4單位流量」這條資訊毫無意義。那麼,有必要建立這些後向弧嗎?

顯然,第1個圖中的畫出來的不是乙個最大流。

但是,如果我們把s -> v2 -> v1 -> t這條路徑經過的弧的流量都增加2,就得到了該網路的最大流。

注意到這條路徑經過了一條後向弧:(v2,v1)。

如果不設立後向弧,演算法就不能發現這條路徑。

**從本質上說,後向弧為演算法糾正自己所犯的錯誤提供了可能性,它允許演算法取消先前的錯誤的行為(讓2單位的流從v1流到v2)

注意,後向弧只是概念上的,在程式中後向弧與前向弧並無區別.

**增廣路

增廣路定義:在殘量網路中的一條從s通往t的路徑,其中任意一條弧(u,v),都有r[u,v]>0。

如圖綠色的即為一條增廣路。

看了這麼多概念相信大家對增廣路演算法已經有大概的思路了吧。

**增廣路演算法

增廣路演算法:每次用bfs找一條最短的增廣路徑,然後沿著這條路徑修改流量值(實際修改的是殘量網路的邊權)。當沒有增廣路時,演算法停止,此時的流就是最大流。

**增廣路演算法的效率

設n = |v|,  m = |e|

每次增廣都是一次bfs,效率為o(m),而在最壞的情況下需要(n-2增廣。(即除源點和匯點外其他點都沒有連通,所有點都只和s與t連通)

所以,總共的時間複雜度為o(m*n),所以在稀疏圖中效率還是比較高的。

hdoj 1532是一道可以作為模板題目練手。

模板**:

[cpp]view plain

copy

print?

#include 

#include 

#include 

#include 

#include 

#include 

#include 

using

namespace std;  

const

int n = 1100;  

const

int inf = 0x3f3f3f3f;  

struct node  

;  vectorv[n];  

bool used[n];  

void add_node(int from,int to,int cap)  //重邊情況不影響

);  

v[to].push_back((node));  

}  int dfs(int s,int t,int f)  

}  }  return 0;  

}  int max_flow(int s,int t)  

}  int main()  

printf("%d\n",max_flow(1,m));  

}  }  

#include #include #include #include #include #include #include using namespace std;

const int n = 1100;

const int inf = 0x3f3f3f3f;

struct node

;vectorv[n];

bool used[n];

void add_node(int from,int to,int cap) //重邊情況不影響

); v[to].push_back((node));

}int dfs(int s,int t,int f)}}

return 0;

}int max_flow(int s,int t)

}int main()

{ int n,m;

while(~scanf("%d%d",&n,&m))

{memset(v,0,sizeof(v));

for(int i=0;i

最大網路流

1 基本概念和術語 1 網路 g 是乙個簡單有向圖,g v,e v 在 v 中指定乙個頂點 s 稱為源 和另乙個頂點 t 稱為匯 有向圖 g 的每一條邊 v,w e 對應有乙個值 cap v,w 0 稱為邊的容量 這樣的有向圖 g 稱作乙個網路 2 網路流 網路上的流 是定義在網路的邊集合 e 上的...

最大網路流

圖中有兩個點源結點s和匯點t。源結點是網路流的起點,匯點是流的終點 給定乙個流網路g 乙個源結點s 乙個匯點t,找到值最大的乙個流 定義 出發點為源點,接受流量 的匯聚點為匯點,邊上的權值為可以流過的最大值 殘存網路gf 由仍可以對流量進行增加 減少的邊構成 流過的量不超過容量的邊 包含原圖中的邊,...

最大網路流問題

參考博文 之前參加阿里巴巴的筆試碰到一最大網路流的題目。因為之前沒有看過這類演算法,所以還是自然沒做出。今天抽空看了看。了解了下基本概念和求解流程。這裡簡單總結下。本圖示最大流的乙個例項。由此,可以引出最大流的一些基本的定義和概念 可以這樣看,圖就是一種管道,管道有最大通過流量的限制,圖中邊的權值就...