1.什麼是網路最大流
形象的來說,網路最大流其實就是這樣乙個生活化的問題:現在有乙個由許多水管組成的水流系統,每一根管道都有自己的最大通過水流限制(流量),
超過這個限制水管會爆(你麻麻就會來找你喝茶qwq)。現在,給定你乙個出水口(原點),乙個出水口(匯點),求這個網路中水流量的最大值。
????看起來很簡單對不對?在我們看起來的確是這樣的,而這部分的難點也確實不在思路上,而是在於演算法設計以及**實現上。
2.怎麼求解網路最大流
首先想明白一件事情,對於乙個節點來說,他接受的流量一定小於等於他給出的流量之和,否則,水管一定會爆掉。而對於乙個節點來說,
他接受的流量有可能大於任意乙個他出邊的流量,因為這個節點可以把接受流給出到不同的水管上,進而實現分流。
有了這兩點,思路就很清晰了(貪心算):
1.首先,我們需要尋找一條可行的流量方案(此時,不一定為最大流量)。
2.然後我們依次擴充套件這條路徑上的所有節點,看看這個節點是否還可以接受流量,直到已經滿流。
3.重複上述步驟,直到沒有可行流動路徑。
4.此時我們累加的流量即為網路最大流,我們把這種方法稱為最大流dinic演算法
3.實現細節
這種演算法看起來簡單,實際上實現起來會遇到許多小毛病,以及許多很難理解的**實現,這裡舉乙個栗子
在步驟2的時候我們採用dfs進行擴充套件,也稱為網路最大流的擴充套件部分演算法,需要借助到反邊這樣乙個概念,即:兩個節點a,b間有一條權值為w無向邊。
我們就把他拆分成一條由a指向b的有向邊與一條由b指向a的有向邊,其中,這兩條邊的權值之和為w,這樣一來一回,兩者相互抵消巧妙的實現了回溯
上**:qwq
#include#include#include#include#define n 1000005看完關注哦~#define m 4*1000005
#define inf 0xfffffff
using namespace std;
int read()//快讀
while(c<='9'&&c>='0')
return num*k;
}struct node
;node edge[2*m];
int cnt_edge=1,n,m,s,t;
long long ans=0;
int last[n],deep[n];
void add_edge(int u,int v,int w)
bool bfs() //判斷是否有通路
} }return deep[t]!=-1;
}int dfs(int now,int flow) //flow為當前流量
} return flow-delta; //返回這裡留下去了多少 ,即當前點的最大流量
} int main ()
while(bfs()) ans+=dfs(s,inf);
printf("%lld\n",ans);
return 0;
}
網路最大流 Dinic
dinic求最大流分為兩步 bfs構造層次圖 dfs尋找增廣路 字面理解,其實就是給圖分層 設源點為第0層 從源點出發最少只要一步可以到達的就是第1層 最少兩步到達的是第二層 依次類推直到匯點 如下圖所示 在網路流中 求取層次圖需要先判斷該邊是否有剩餘容量 若層次圖可以延伸到匯點 則說明最大流還可以...
網路最大流 Dinic
存圖方式 鄰接表,鄰接矩陣 圖的遍歷 dfs,bfs 我們舉個例子吧 有乙個毒瘤水管工,他會造水管,有一天他造了乙個水管網路,就像乙個圖。其中有乙個點只有出邊,就是起點,還有乙個點只有入邊,是終點。點之間有一些管子,這些管子都有單位時間內的容量,現在毒瘤水管工想知道,他的管子在單位時間裡在起點終點之...
網路流最大流 Dinic演算法
o n 2 m 的演算法 比ek的o n m 2 優很多 ek通常解決10 3 10 4規模的網路 而dinic能解決10 4 10 5的網路 dinic演算法的思想也是分階段地在層次網路中增廣。它與最短增廣路演算法不同之處是 最短增廣路每個階段執行完一次bfs增廣後,要重新啟動bfs從源點vs開始...