【模板】网络最大流(EK、Dinic、ISAP)(网络流)/洛谷P3376

题目链接

https://www.luogu.com.cn/problem/P3376

题目大意

输入格式
第一行包含四个正整数 \(n,m,s,t\),分别表示点的个数、有向边的个数、源点序号、汇点序号。
接下来\(m\)行,每行包含三个正整数 \(u_i,v_i,w_i\),表示第 \(i\) 条有向边从 \(u_i\) 出发,到达 \(v_i\),边权为 \(w_i\)(即该边最大流量为 \(w_i\) )。
输出格式
一行,包含一个正整数,即为该网络的最大流。

题目解析

(待补充,咕咕咕。。。)

参考代码

\(EK\)

#include <bits/stdc++.h>
using namespace std;
const int N = 205;
const long long INF = (1LL << 32);
struct Edge{
    int from, to;
    long long cap, flow;
};
int n, m, s, t;
long long a[N];
int p[N];
vector <Edge> e;
vector <int> G[N];

void addEdge(int from, int to, int cap, int i)
{
    e.push_back((Edge){from, to, cap, 0});
    e.push_back((Edge){to, from, 0, 0});
    G[from].push_back(i << 1);
    G[to].push_back((i << 1)+1);
}
long long maxflow()
{
    long long flow = 0;
    while (1)
    {
        memset(a, 0, sizeof(a));
        a[s] = INF;
        queue <int> q;
        q.push(s);
        while (!q.empty())
        {
            int x = q.front();
            q.pop();
            for (int i=0; i<G[x].size(); ++i)
            {
                Edge &b = e[G[x][i]];
                if (!a[b.to] && b.cap > b.flow)
                {
                    p[b.to] = G[x][i];
                    a[b.to] = min(a[x], b.cap-b.flow);
                    q.push(b.to);
                }
            }
            if (a[t]) break;
        }
        if (!a[t]) break;
        for (int u=t; u!=s; u=e[p[u]].from)
        {
            e[p[u]].flow += a[t];
            e[p[u]^1].flow -= a[t];
        }
        flow += a[t];
    }
    return flow;
}
int main()
{
    int u, v, w;
    scanf("%d%d%d%d", &n, &m, &s, &t);
    for (int i=0; i<m; ++i)
    {
        scanf("%d%d%d", &u, &v, &w);
        addEdge(u, v, w, i);
    }
    printf("%lld\n", maxflow());
    return 0;
}

\(Dinic\)

#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int INF = 2147483647;
const int N = 205;
struct Edge{
    int from, to, cap, flow;
};
int cur[N], depth[N];
int n, m, s, t;
vector <Edge> e;
vector <int> G[N];

void addEdge(int u, int v, int w, int i)
{
    e.push_back((Edge){u, v, w, 0});
    e.push_back((Edge){v, u, 0, 0});
    G[u].push_back(i);
    G[v].push_back(i^1);
}
int BFS()
{
    queue <int> Q;
    memset(depth, 0, sizeof depth);
    depth[s] = 1;
    Q.push(s);
    while (!Q.empty())
    {
        int u = Q.front(); Q.pop();
        for (int i = 0; i < G[u].size(); ++i) {
            Edge& b = e[G[u][i]];
            if (!depth[b.to] && b.cap > b.flow)
            {
                depth[b.to] = depth[u] + 1;
                Q.push(b.to);
            }
        }
    }
    return depth[t];
}
int DFS(int x, int a)
{
    if (x == t || !a) return a;
    int flow = 0;
    for (int& i = cur[x]; i < G[x].size(); ++i) {
        Edge& b = e[G[x][i]];
        if (depth[b.to] == depth[x]+1 && b.cap > b.flow)
        {
            if (int c = DFS(b.to, min(a, b.cap - b.flow)))
            {
                b.flow += c;
                e[G[x][i]^1].flow -= c;
                flow += c;
                a -= c;
                if (!a) break;
            }
        }
    }
    return flow;
}
ll maxFlow_Dinic()
{
    ll ans = 0;
    while (BFS()) {
        memset(cur, 0, sizeof cur);
        ans += DFS(s, INF);
    }
    return ans;
}
int main()
{
    scanf("%d%d%d%d", &n, &m, &s, &t);
    for (int i = 0; i < m; ++i) {
        int u, v, w;
        scanf("%d%d%d", &u, &v, &w);
        addEdge(u, v, w, i << 1);
    }
    printf("%lld\n", maxFlow_Dinic());
    return 0;
}

\(ISAP\)

#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 205;
const int INF = 2147483647;
struct Edge {
    int from, to, cap, flow;
};
int n, m, s, t, cnt, gap[N], cur[N], dep[N];
vector <int> G[N];
vector <Edge> e;

void addEdge(int u, int v, int w, int i) 
{
    e.push_back((Edge){u, v, w, 0});
    e.push_back((Edge){v, u, 0, 0});
    G[u].push_back(i);
    G[v].push_back(i^1);
}
void init()
{
    memset(gap, 0, sizeof gap);
    memset(cur, 0, sizeof cur);
    memset(dep, 0, sizeof dep);
    ++gap[dep[t] = 1];
    queue <int> Q;
    Q.push(t);
    while (!Q.empty()) {
        int x=Q.front(); Q.pop();
        for (int i = 0; i < G[x].size(); i++)
        {
            int v = e[G[x][i]].to;
            if (!dep[v])
            {
                ++gap[dep[v] = dep[x]+1];
                Q.push(v);
            }
        }
    }
}
int augment(int x, int a)
{
    if (x == t || !a) return a;
    int flow = 0;
    for (int &i=cur[x]; i < G[x].size(); i++)
    {
        Edge& b = e[G[x][i]];
        if (dep[x] == dep[b.to] + 1 && b.cap > b.flow) {
            int tmp = augment(b.to, min(a, b.cap - b.flow));
            flow += tmp;
            a -= tmp;
            b.flow += tmp;
            e[G[x][i]^1].flow -= tmp;
            if (!a) return flow;
        }
    }
    if (!(--gap[dep[x]])) dep[s] = cnt+1;
    ++gap[++dep[x]], cur[x] = 0;
    return flow;
}
ll maxFlow_ISAP()
{
    cnt = n; //Num_of_nodes -> cnt
    init();
    ll ans = 0;
    while (dep[s] <= cnt) ans += augment(s, INF);
    return ans;
}
int main() 
{
    scanf("%d%d%d%d", &n, &m, &s, &t);
    for (int i = 0; i < m; i++) {
        int u, v, w;
        scanf("%d%d%d", &u, &v, &w);
        addEdge(u, v, w, i << 1);
    }
    printf("%lld\n", maxFlow_ISAP());
    return 0;
}

感谢支持!

posted @ 2020-08-26 18:20  Chiron-zy  阅读(157)  评论(0编辑  收藏  举报