洛谷 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
",ans);
    return 0;
}