网络流,最大流,EK算法
概念
最大流:
从源点流向汇点的最大流量
增广路:
一条从源点到汇点的所有边的剩余容量>=0的路径
残留网:
由网络中所有结点和剩余容量大于0的边构成的子图,这里的边包括有向边和其反向边
模板题:
洛谷p3376
code:
#include<iostream>
#include<algorithm>
#include<queue>
#include<cstring>
using namespace std;
typedef long long LL;
const int N=2e2+10,M=5e3+10,INF=0x3f3f3f3f;
//id=1,从2,3开始配对
LL n,m,ne[M<<1],h[N],e[M<<1],c[M<<1],id=1,S,T;
LL mf[N],pre[N];
void add(int u,int v,int w){
++id;
e[id]=v;
ne[id]=h[u];
c[id]=w;
h[u]=id;
}
bool bfs(){//找增广路
memset(mf,0,sizeof mf);
mf[S]=INF;
queue<int> q;
q.push(S);
while(q.size()){
int u=q.front();
q.pop();
for(int i=h[u];i;i=ne[i]){
LL v=e[i],w=c[i];
if(!mf[v]&&w){
mf[v]=min(mf[u],w);
pre[v]=i;//存前驱边
q.push(v);
if(v==T){
return true;
}
}
}
}
return false;
}
LL EK(){//累加可行流
LL flow=0;
while(bfs()){//更新残留网
int v=T;
while(v!=S){
int i=pre[v];
c[i]-=mf[T];
c[i^1]+=mf[T];
v=e[i^1];
}
flow+=mf[T];
}
return flow;
}
int main(){
cin.tie(nullptr)->sync_with_stdio(false);
cin>>n>>m>>S>>T;
for(int i=1;i<=m;i++){
int u,v,w;
cin>>u>>v>>w;
add(u,v,w);
add(v,u,0);
}
cout<<EK()<<endl;
return 0;
}

浙公网安备 33010602011771号