【模板】网络最大流

题目描述:

给出一个网络图,以及其源点和汇点,求出其网络最大流。

题解:

1.Dinic

Dinic算法可用于求最大流。

算法过程:

bfs分层+dfs搜最大流。

注意:残余网络。

代码:

#include<queue>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define N 10050
#define M 100050
#define ll long long
int n,m,s,t,hed[N],cnt=-1,cur[N];
const int inf = 0x3f3f3f3f;
struct EG
{
    int to,nxt;
    ll vl;
}e[2*M];
void ae(int f,int t,ll v)
{
    e[++cnt].to = t;
    e[cnt].vl = v;
    e[cnt].nxt = hed[f];
    hed[f] = cnt;
}
int dep[N];
bool bfs()
{
    memset(dep,0x3f,sizeof(dep));
    memcpy(cur,hed,sizeof(cur));
    dep[s]=0;
    queue<int>q;
    q.push(s);
    while(!q.empty())
    {
        int u = q.front();
        q.pop();
        for(int j=hed[u];~j;j=e[j].nxt)
        {
            int to = e[j].to;
            if(e[j].vl&&dep[to]>dep[u]+1)
            {
                dep[to]=dep[u]+1;
                q.push(to);
            }
        }
    }
    if(dep[t]!=inf)return 1;
    return 0;
}
ll dfs(int u,ll lim)
{
    if(!lim||u==t)return lim;
    ll fl=0,f;
    for(int j=cur[u];~j;j=e[j].nxt)
    {
        cur[u]=j;
        int to = e[j].to;
        if(dep[to]==dep[u]+1&&(f=dfs(to,min(lim,e[j].vl))))
        {
            fl+=f;
            lim-=f;
            e[j].vl-=f;
            e[j^1].vl+=f;
            if(!lim)break;
        }
    }
    return fl;
}
ll dinic()
{
    ll ret = 0;
    while(bfs())
        ret+=dfs(s,inf);
    return ret;
}
int main()
{
    memset(hed,-1,sizeof(hed));
    scanf("%d%d%d%d",&n,&m,&s,&t);
    for(int f,t,v,i=1;i<=m;i++)
    {
        scanf("%d%d%d",&f,&t,&v);
        ae(f,t,1ll*v),ae(t,f,0);
    }
    printf("%lld\n",dinic());
    return 0;
}

 

posted @ 2018-11-20 20:23  LiGuanlin  阅读(192)  评论(0编辑  收藏  举报