前置-重贴标签算法的问题

P3376 【模板】网络最大流

徐一凡 @ 2022-04-19 20:45:24

#include<iostream>
#include<vector>
#include<list>

using namespace std;

constexpr long long inf = 1000000000000000000ll;
constexpr int iinf = 1000000000;

void push(vector<vector<long long>>& remnant,
          vector<long long>& preflow, int i, int j)
{
    long long amount = min(remnant[i][j], preflow[i]);
    remnant[i][j] -= amount;
    remnant[j][i] += amount;
    preflow[i] -= amount;
    preflow[j] += amount;
}

void discharge(vector<vector<long long>>& remnant,
               vector<long long>& preflow,
               vector<int>& label,
               vector<int>& current, int i)
{
    int n = remnant.size();

    while (preflow[i] > 0)
    {
        if (current[i] == n)
        {
            current[i] = 0;
            int min_label = iinf;

            for (int j = 0; j < n; ++j)
            {
                if (remnant[i][j] > 0)
                {
                    min_label = min(min_label, label[j]);
                }
            }

            label[i] = min_label + 1;
        }
        else
        {
            if (label[current[i]] == label[i] - 1 and remnant[i][current[i]] > 0)
            {
                push(remnant, preflow, i, current[i]);
            }

            ++current[i];
        }
    }
}

long long relable_to_front(const vector<vector<int>>& g, int s, int t)
{
    int n = g.size();
    vector<vector<long long>> remnant(n, vector<long long>(n));
    vector<long long> preflow(n);
    vector<int> label(n), current(n);

    preflow[s] = inf;
    label[s] = n;

    for (int i = 0; i < n; ++i)
    {
        for (int j = 0; j < n; ++j)
        {
            remnant[i][j] = g[i][j];
        }
    }

    for (int i = 0; i < n; ++i)
    {
        push(remnant, preflow, s, i);
    }

    list<int> l;

    for (int i = 0; i < n; ++i)
    {
        if (i != s and i != t)
        {
            l.push_back(i);
        }
    }

    list<int>::iterator it = l.begin();

    while (it != l.end())
    {
        int old_label = label[*it];

        discharge(remnant, preflow, label, current, *it);

        if (label[*it] > old_label)
        {
            l.splice(l.begin(), l, it);
        }

        ++it;
    }

    return preflow[t];
}

int main()
{
    int n, m, s, t;
    cin >> n >> m >> s >> t;
    --s, --t;

    vector<vector<int>> g(n, vector<int>(n));

    for (int i = 0; i < m; ++i)
    {
        int x, y, v;
        cin >> x >> y >> v;
        --x, --y;

        g[x][y] = v;
    }

    long long ans = relable_to_front(g, s, t);

    cout << ans << "\n";
    return 0;
}

8 #9 #10 过不了。有可能是没考虑反向边,但是没有反向边的 #9 也没过。


by 徐一凡 @ 2022-04-25 19:02:46

已解决。竟是因为有重边,且重边容量叠加后会超出int。


|