フロント
•フローネットワーク(ネットワークフロー)\(Gは、=(V、E)が\)有向グラフであり、各エッジ\((U、V)\ E \で) 非負容量(キャパシティ)を有している(\ C(U、V)> = 0 \) 。れないため(E \)\の\((U、V)\)、所定の\を(C(U、V)= 0 \)
•二つの特別なノードを有します点:ソース(ソース)\(VにおけるS(S \)\)とシンク(シンク)が\(VにおけるT(T \)\) 。
•仮定他の点vについて、プレゼンス・パスその\(S \のRARRのV \ RARRトン\)
•サイドストリームはの関数である\(F(U、V)\)流量関数、\(F(x、y)を V、VのY \)で\(X \ \) 満たされます。
•容量制限:\(\ FORALL(U、V)、\; 0 \ Fル(U、V)\ Cル(U、V)\)
•対称:\(F(U、V)= - F(V、U)\)
•バランス:いないため\(S \)または\(T \)その他の点\(U \)がある(\ \和\ limits_ {Vが Vで\} F(U、V)= 0 \)
:•流量は全体のネットワーク(すなわちSからの流出流量)で定義され(| F | = \ SUM \ limits_ {VにおけるV \} F(S、V)\)\
•最大フロー問題は:見つけるストリーム機能\ (F \) 、そのため、ネットワークの最大流量
•その他
同等の条件:
1)最大流量Fである。
2)経路増強残存ネットワーク
3)カット(S、T)の存在、|をf | = Cの(S、T)
パスを増強する辺の最小数を探してたびに増大すること
•定理:ワイドによりO(nm)の時間まで
•エドモンズ-カープ:BFSは、各増強経路を見つけ、追加の保守情報
•Dinic:BFS複数階層グラフ構造、DFSは増強のパスを見つけます。追加情報:
(uの値を開始点から)レベル
最大流量
luogu3376ネットワーク最大流量[テンプレート]
すべてのBFSはありません増強経路グラフまでの経路を増強見つけます
#include<bits/stdc++.h>
using namespace std;
#define Max(x,y) ((x)>(y)?(x):(y))
#define Min(x,y) ((x)>(y)?(y):(x))
const int N=10000+5,M=100000+5,inf=0x3f3f3f3f,P=19650827;
int n,m,s,t,maxflow=0,pre[N],incf[N];
template <class t>void rd(t &x){
x=0;int w=0;char ch=0;
while(!isdigit(ch)) w|=ch=='-',ch=getchar();
while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
x=w?-x:x;
}
int head[N],tot=1;
struct edge{int v,w,nxt;}e[M<<1];
void add(int u,int v,int w){
e[++tot]=(edge){v,w,head[u]},head[u]=tot;
}
bool vis[N];
queue<int> q;
bool bfs(){
while(!q.empty()) q.pop();
memset(vis,0,sizeof(vis));
q.push(s),vis[s]=1,incf[s]=inf;
while(!q.empty()){
int u=q.front();q.pop();
for(int i=head[u],v,w;i;i=e[i].nxt)
if(w=e[i].w){
v=e[i].v;
if(vis[v]) continue;
incf[v]=Min(incf[u],w),pre[v]=i;
q.push(v),vis[v]=1;
if(v==t) return 1;
}
}
return 0;
}
void upd(){
int x=t;
while(x!=s){
int i=pre[x];
e[i].w-=incf[t],e[i^1].w+=incf[t];
x=e[i^1].v;
}
maxflow+=incf[t];
}
int main(){
rd(n),rd(m),rd(s),rd(t);
for(int i=1,u,v,w;i<=m;++i)
rd(u),rd(v),rd(w),add(u,v,w),add(v,u,0);
while(bfs())
upd();
printf("%d",maxflow);
return 0;
}