洛谷 P3376【模板】網路最大流
阿新 • • 發佈:2019-01-22
題目描述
如題,給出一個網路圖,以及其源點和匯點,求出其網路最大流。
【題目分析】
網路流模板題目 (Dinic)
【程式碼】
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <set>
#include <map>
#include <string>
#include <algorithm>
#include <vector>
#include <iostream>
#include <queue>
using namespace std;
#define maxn 200005
#define inf 1000000000
int read()
{
int x=0,f=1; char ch=getchar();
while (ch<'0'||ch>'9') {if (ch=='-') f=-1; ch=getchar();}
while (ch>='0'&&ch<='9') {x=x*10+ch-'0'; ch=getchar();}
return x*f;
}
int fr[maxn],to[maxn],ne[maxn],h[maxn],mp[maxn],f[maxn];
int n,m,en,S,T;
queue <int> q;
void add(int a,int b,int r)
{
fr[en]=a;to[en]=b;ne[en]=h[a];f[en]=r;h[a]=en++;
fr[en]=b;to[en]=a;ne[en]=h[b];f[en]=0;h[b]=en++;
}
bool tell()
{
memset(mp,-1,sizeof mp);
q.push(S); mp[S]=0;
while (!q.empty())
{
int x=q.front();q.pop();
for (int i=h[x];i>=0;i=ne[i])
if (mp[to[i]]==-1&&f[i])
{
mp[to[i]]=mp[x]+1;
q.push(to[i]);
}
}
if (mp[T]==-1) return false;
return true;
}
int zeng(int k,int now)
{
if (k==T) return now;
int ret=0;
for (int i=h[k];i>=0&&now>ret;i=ne[i])
if (mp[k]+1==mp[to[i]]&&f[i]!=0)
{
int tmp=zeng(to[i],min(now-ret,f[i]));
f[i]-=tmp; f[i^1]+=tmp; ret+=tmp;
}
if (!ret) mp[k]=-1;
return ret;
}
int main()
{
memset(h,-1,sizeof h);
n=read();m=read();S=read();T=read();
for (int i=1;i<=m;++i)
{
int a=read(),b=read(),c=read();
add(a,b,c);
}
int ans=0,tmp;
while (tell()) while (tmp=zeng(S,inf)) ans+=tmp;
printf("%d\n",ans);
}