洛谷 P3376 【模板】网络最大流
Ford-Fulkerson算法
关于反向建边,看下面这组数据
6 7 1 6
1 2 1
2 4 1
4 6 1
1 3 1
3 4 1
2 5 1
5 6 1
对应的图为
由此看出,无反向的边的话,只有1->2->4->6这条路。反向更新后第二次寻找增广路为
1->3->4->2->5->6。相当于将第一次找的增广路为1->2->5->6
#include<bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
#define int long long
int n,m,s,t,dis[205][205],vis[205],minn[205],pre[205],res;
vector<int> v[5005];
bool bfs(){
queue<int> q;
memset(vis,0,sizeof(vis));
q.push(s);
minn[s]=inf;
vis[s]=1;
while(!q.empty()){
int x=q.front();
q.pop();
for(int i=0;i<v[x].size();i++){
int to=v[x][i];
int w=dis[x][to];
if(w&&!vis[to]){
minn[to]=min(minn[x],w);
pre[to]=x;
q.push(to);
vis[to]=1;
if(to==t)return 1;
}
}
}
return 0;
}
void update(){
int x=t;
while(x!=s){
int p=pre[x];
dis[p][x]-=minn[t];
dis[x][p]+=minn[t];
x=p;
}
res+=minn[t];
}
signed main(){
cin>>n>>m>>s>>t;
int x,y,z;
for(int i=1;i<=m;i++){
cin>>x>>y>>z;
v[x].push_back(y);
v[y].push_back(x);
dis[x][y]+=z;
}
while(bfs()){
update();
}
cout<<res<<endl;
return 0;
}
/*
6 7 1 6
1 2 1
2 4 1
4 6 1
1 3 1
3 4 1
2 5 1
5 6 1
*/