带上下界的网络流

对于每条边加了个下界限制B(e),这样每条边需满足条件B(e) <= F(e) <= C(e)。
1)对于无源点和汇点
对于每一条边e,将其分离成两条边e’和e’’,其中的容量C(e’) = C(e) - B(e),C(e’’) = B(e)
这样分离后只需要e’'满流即可
步骤:新建源点S和汇点T,对原图的每一条边e = <u, v>,建立从u到v容量C(e) - B(e)的弧,从u到T,S到v分别建立一条容量为B(e)的弧。求一边新网络的最大流
2)对有源点和汇点
只需要先将转换为无源点和汇点的网络,将汇点建立一条容量为无穷大的边到源点

普通网络流板子

#pragma comment(linker, "/STACK:102400000,102400000")
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
inline int read()
{
    int k = 0, flag = 1;
    char c;
    c = getchar();
    if (c == '-')
        flag = 0, c = getchar();
    while (!isdigit(c))
        c = getchar();
    while (isdigit(c))
    {
        k = (k << 3) + (k << 1) + c - '0';
        c = getchar();
    }
    return flag ? k : -k;
}
const int maxn = 1e4 + 10;
const int INF = 0x3f3f3f3f;
struct Edge
{
    int from, to, cap, flow;
    Edge(int u, int v, int c, int f) : from(u), to(v), cap(c), flow(f) {}
};
struct EdmondKarp
{
    int n, m;
    vector<Edge> edges;
    vector<int> G[maxn];
    int a[maxn], p[maxn];

    void init(int n)
    {
        for (register int i = 0; i < n; i++)
            G[i].clear();
        edges.clear();
    }
    void AddEdge(int from, int to, int cap)
    {
        edges.push_back(Edge(from, to, cap, 0));
        edges.push_back(Edge(to, from, 0, 0));
        m = edges.size();
        G[from].push_back(m - 2);
        G[to].push_back(m - 1);
    }
    int Maxflow(int s, int t)
    {
        int flow = 0;
        for (;;)
        {
            memset(a, 0, sizeof(a));
            queue<int> Q;
            Q.push(s);
            a[s] = INF;
            while (!Q.empty())
            {
                int x = Q.front();
                Q.pop();
                for (register int i = 0; i < G[x].size(); i++)
                {
                    Edge &e = edges[G[x][i]];
                    if (!a[e.to] && e.cap > e.flow)
                    {
                        p[e.to] = G[x][i];
                        a[e.to] = min(a[x], e.cap - e.flow);
                        Q.push(e.to);
                    }
                }
                if (a[t])
                    break;
            }
            if (!a[t])
                break;
            for (int u = t; u != s; u = edges[p[u]].from)
            {
                edges[p[u]].flow += a[t];
                edges[p[u] ^ 1].flow -= a[t];
            }
            flow += a[t];
        }
        return flow;
    }
};
int main()
{
    EdmondKarp ek;
    // ek.init(n); 点的数量
    // ek.AddEdge(0, i, 1); 加边
    // cout << ek.Maxflow(s, t);
}

猜你喜欢

转载自blog.csdn.net/weixin_40588429/article/details/84072662
今日推荐