我們圍繞一道題來講解吧
藍橋杯-演算法訓練-網路流裸題
首先,何為網路流最大流問題?
可行流:
對於每條路線(u,v)上給定乙個實數f(u,v),滿足 0≤f(u,v)≤c(u,v),則稱f(u,v)為路線(u,v)的流量。而對於一組具有源點和匯點,且總流出量=總流入量,則稱為網路中的一條可行流。
拿例子來說 畫的有點醜 乙個可行流:5。
最大流:
聯絡上下文可知,就知道它是可行流中最大的乙個流。
*所以最大流的情況可能不止一種。
其次,怎麼求最大流呢?
ford-fulkerson(福特-福克森)演算法:
ⅰ.如果存在增廣路徑,就找出一條增廣路徑。
ⅱ.然後眼該條增廣路徑進行更新流量。
這個演算法的乙個關鍵部分就是如何找出增廣路徑:
ⅰ. 找到一條從源點到匯點的路徑,若(u,v)的方向與路徑一致,這稱為正向邊;相反則稱為逆向邊。
ⅱ.該路徑上的每條邊滿足,流量非負,且未達到流量上限,即未達到容量上限。(要分清流量和容量的區別)
*增廣路徑的查詢可以運用bfs或dfs的方法;
再者,現在有了增廣路徑了,如何增廣呢?
設ins為每次最後計算出的增加流量,先使ins=inf(正無窮)
ⅰ.計算ins
若(u,v)為正向邊,則ins=min(ins,c(u,v)-f(u,v));
若(u,v)為逆向邊,則ins=min(ins,f(u,v));
ⅱ.更新流量
若為正向邊,f(u,v)+=ins;
若為逆向邊,f(u,v)-=ins;
完整過程(我偷了個圖過來,我懶得畫 樣例的過程太多了):
**這是樣例最後執行完的圖(希望你們能get到我的意思吧):
最後獻上ac**:
#include
#include
#include
#include
using namespace std;
typedef
long
long ll;
const
int maxn=
1010
;const
int inf=
0x3f3f3f3f
;int n,m,mp[maxn]
[maxn]
;//鄰接矩陣 ;
int mflow=
0,ins=0;
//最大流;每次所得的增加流量;
int book[maxn]
,flow[maxn]
;//每次迴圈標記該邊是否訪問;儲存一條增廣路徑上每條邊的最小流量;
queue<
int> q;
intbfs
(int s,
int t )}}
if( ok )
break;}
if( book[t]==-
1)return-1
;else
return flow[t];}
intmain()
//當存在增廣路徑,更新流量;
while
((ins=
bfs(
1,n))!=
-1)}
printf
("%d"
,mflow)
;return0;
}
網路流 最大流
網路流 題記 網路流是最近講過的最迷演算法 網路流 network flows 是一種模擬水流的解決問題方法,與線性規劃密切相關。非常重視選手在網路流上的建模技巧,畫圖是非常關鍵的。1 最大流 問題引入 有n條溝渠,與水坑s t相連,匯聚成m個點,第i條溝渠的水流的流量為c i 每乙個點的流入量和流...
網路流 最大流
dinic 最大流 head x 從0開始記 這樣便於找反向邊 異或即可 當前弧優化 include include include include include include include define ll long long define ull unsigned long long d...
網路流最大流
源點 起始點 匯點 目標點 流 從源點到匯點的一條路徑 容量 每條管道允許通過的最大流量 流量 通過一條邊的水的實際體積 最大流等於最小割 從起點到終點的一條路徑 尋找從s到t的一條增廣路 在紅色的路線裡,路徑的一條最小流量是3,那麼這條路徑上的邊都減去3,同時反向邊加上3 這條增廣路的乙個流量是3...