码迷,mamicode.com
首页 > 其他好文 > 详细

【模板】网络最大流

时间:2019-07-15 20:06:41      阅读:99      评论:0      收藏:0      [点我收藏+]

标签:sizeof   ++   pop   string   empty   print   scanf   bool   min   

题意简述

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

代码

#include <queue> 
#include <cstdio>
#include <cstring>
#include <algorithm>
int n, m, s, t, cnt = 1, u, v, w, ans;
int h[10010], nxt[200010], va[200010], to[200010], dep[10010], lst[10010];
inline void add_edge(const int& u, const int& v, const int& w)
{
    to[++cnt] = v;
    va[cnt] = w;
    nxt[cnt] = h[u];
    h[u] = cnt;
}
bool bfs()
{
    std::queue <int> q;
    memset(dep, 0, sizeof(dep));
    q.push(t);
    dep[t] = 1;
    while (!q.empty())
    {
        int u = q.front();
        q.pop();
        for (register int i = h[u]; i; i = nxt[i])
            if (va[i ^ 1] && !dep[to[i]])
            {
                dep[to[i]] = dep[u] + 1;
                if (to[i] == s) return 1;
                q.push(to[i]);
            }
    }
    return 0;
}
int dfs(const int& u, int flow)
{
    int ss = 0;
    if (u == t) return flow;
    for (int& i = lst[u]; i; i = nxt[i])
        if (dep[to[i]] == dep[u] - 1 && va[i])
        {
            int tmp = dfs(to[i], std::min(flow, va[i]));
            va[i] -= tmp;
            va[i ^ 1] += tmp;
            flow -= tmp;
            ss += tmp;
            if (!flow) return ss;
        }
    if (!ss) dep[u] = 0;
    return ss;
}
int main()
{
    scanf("%d%d%d%d", &n, &m, &s, &t);
    for (register int i = 1; i <= m; ++i)
    {
        scanf("%d%d%d", &u, &v, &w);
        add_edge(u, v, w);
        add_edge(v, u, 0);
    }
    while (bfs())
    {
        for (register int i = 1; i <= n; ++i) lst[i] = h[i];
        ans += dfs(s, 0x7fffffff);
    }
    printf("%d\n", ans);
}

【模板】网络最大流

标签:sizeof   ++   pop   string   empty   print   scanf   bool   min   

原文地址:https://www.cnblogs.com/xuyixuan/p/11191008.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!