题目描述
如题,给出一个网络图,以及其源点和汇点,求出其网络最大流。
输入格式
第一行包含四个正整数 (n,m,s,t),分别表示点的个数、有向边的个数、源点序号、汇点序号。
接下来M行每行包含三个正整数 (u_i,v_i,w_i),表示第 (i) 条有向边从 (u_i) 出发,到达 (v_i),边权为 (w_i)(即该边最大流量为 (w_i))。
输出格式
一行,包含一个正整数,即为该网络的最大流。
已加入当前弧优化
#include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int N=1e4+5,M=2e5+5,inf=1<<30;
int nxt[M],head[N],go[M],edge[M],tot=1;
inline void add(int u,int v,int w){
nxt[++tot]=head[u],head[u]=tot,go[tot]=v,edge[tot]=w;
nxt[++tot]=head[v],head[v]=tot,go[tot]=u,edge[tot]=0;
}
int n,m,s,t,maxflow;
int d[N],now[N];
bool bfs(){
queue<int>q;
memset(d,0,sizeof(d));
q.push(s); d[s]=1;
now[s]=head[s];
while(q.size()){
int u=q.front(); q.pop();
for(int i=head[u];i;i=nxt[i]){
int v=go[i];
if(edge[i]&&!d[v]){
q.push(v);
d[v]=d[u]+1;
now[v]=head[v];
if(v==t)return 1;
}
}
}
return 0;
}
int dinic(int u,int flow){
if(u==t)return flow;
for(int &i=now[u];i;i=nxt[i]){
int v=go[i];
if(edge[i]&&d[v]==d[u]+1){
int k=dinic(v,min(flow,edge[i]));
if(!k)d[v]=0;
else{
edge[i]-=k;
edge[i^1]+=k;
return k;
}
}
}
return 0;
}
signed main(){
cin>>n>>m>>s>>t;
for(int i=1,u,v,w;i<=m;i++){
scanf("%d%d%d",&u,&v,&w);
add(u,v,w);
}
int flow=0;
while(bfs())
while(flow=dinic(s,inf))maxflow+=flow;
cout<<maxflow<<endl;
}