洛谷 P3376 【模板】网络最大流
洛谷 P3376 【模板】网络最大流
题目描述
如题,给出一个网络图,以及其源点和汇点,求出其网络最大流。
输入格式
第一行包含四个正整数 n,m,s,tn,m,s,t,分别表示点的个数、有向边的个数、源点序号、汇点序号。
接下来M行每行包含三个正整数 u_i,v_i,w_iu**i,v**i,w**i,表示第 ii 条有向边从 u_iu**i 出发,到达 v_iv**i,边权为 w_iw**i(即该边最大流量为 w_iw**i)。
输出格式
一行,包含一个正整数,即为该网络的最大流。
题解:
代码:
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#define int long long
using namespace std;
const int maxn=210;
const int maxm=5010;
const int INF=1e18;
int n,m,s,t;
int tot=1,to[maxm<<1],nxt[maxm<<1],head[maxn],val[maxm<<1];
int flow[maxn],pre[maxn];
bool v[maxn];
void add(int x,int y,int z)
{
to[++tot]=y;
nxt[tot]=head[x];
val[tot]=z;
head[x]=tot;
}
bool bfs()
{
memset(pre,-1,sizeof(pre));
queue<int> q;
q.push(s);
flow[s]=INF;
while(!q.empty())
{
int x=q.front();
q.pop();
if(x==t)
break;
for(int i=head[x];i;i=nxt[i])
{
int y=to[i];
if(val[i]==0||pre[y]>0)
continue;
pre[y]=i;
flow[y]=min(flow[x],val[i]);
q.push(y);
}
}
return pre[t]!=-1;
}
signed main()
{
scanf("%lld%lld%lld%lld",&n,&m,&s,&t);
for(int i=1;i<=m;i++)
{
int x,y,z;
scanf("%lld%lld%lld",&x,&y,&z);
add(x,y,z);
add(y,x,0);
}
int ans=0;
while(bfs())
{
ans+=flow[t];
for(int i=t;i!=s;i=to[pre[i]^1])
{
val[pre[i]]-=flow[t];
val[pre[i]^1]+=flow[t];
}
}
printf("%lld\n",ans);
return 0;
}