关于最后一组测试数据
查看原帖
关于最后一组测试数据
390898
app1eDog楼主2023/4/20 16:53

先说我的问题,代码在最后。

我尝试把每一条边权都加上一个较大的值,强行把连边的边权变成正数,未连边的值为零。然后 wa 在了最后一个点。最后一组数据左侧的 498 连接了右侧的 496,这显然是不对的,这两个点之间甚至没有边。

接着我把未连边的值变成 −INF=−1e18-INF = -1e18 就可以了,那这样我强行把边权变正就没有意义了。

带有负权边的完美匹配不能把权值变正再做吗?

接着是我的 AC 代码。

// created on Lucian Xu's Laptop

#include <bits/stdc++.h>

// using namespace std;

typedef unsigned int UI;
typedef unsigned long long ULL;
typedef long long LL;
typedef unsigned long long ULL;
typedef std::pair<int, int> PII;
typedef std::pair<int, LL> PIL;
typedef std::pair<LL, int> PLI;
typedef std::pair<LL, LL> PLL;
typedef std::vector<int> vi;
typedef std::vector<vi> vvi;
typedef std::vector<LL> vl;
typedef std::vector<vl> vvl;
typedef std::vector<PII> vpi;

#define typet typename T
#define typeu typename U
#define types typename... Ts
#define tempt template <typet>
#define tempu template <typeu>
#define temps template <types>
#define tandu template <typet, typeu>

#define rep(i, l, r) for (auto i = (l); i <= (r); i++)
#define per(i, r, l) for (auto i = (r); i >= (l); i--)
#define ff first
#define ss second
#define makepair make_pair
#define pushback push_back
#define endl '\n'
#define all(v) v.begin(), v.end()
#define rall(v) v.rbegin(), v.rend()

#ifdef LOCAL
#include "debug.h"
#else
#define debug(...) \
    do {           \
    } while (false)
#endif

constexpr int N = 2e5 + 10;
constexpr int mod = 998244353;
constexpr int inf = 0x3f3f3f3f;
constexpr LL INF = 1e18;
const double pi = std::acos(-1);
const double eps = 1e-6;

constexpr int lowbit(int x) { return x & -x; }
constexpr int add(int x, int y) { return x + y < mod ? x + y : x - mod + y; }
constexpr int sub(int x, int y) { return x < y ? mod + x - y : x - y; }
constexpr int mul(LL x, int y) { return x * y % mod; }
constexpr void Add(int& x, int y) { x = add(x, y); }
constexpr void Sub(int& x, int y) { x = sub(x, y); }
constexpr void Mul(int& x, int y) { x = mul(x, y); }
constexpr int pow(int x, int y, int z = 1) {
    for (; y; y /= 2) {
        if (y & 1) Mul(z, x);
        Mul(x, x);
    }
    return z;
}
temps constexpr int add(Ts... x) {
    int y = 0;
    (..., Add(y, x));
    return y;
}
temps constexpr int mul(Ts... x) {
    int y = 1;
    (..., Mul(y, x));
    return y;
}

tempt bool Max(T& x, const T& y) { return x < y ? x = y, true : false; }
tempt bool Min(T& x, const T& y) { return x > y ? x = y, true : false; }

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);
    std::cout.tie(0);

    int n, m;
    std::cin >> n >> m;
    vvl e(n + 1, vl(n + 1, -INF));
    for (int i = 1; i <= m; i++) {
        int u, v, w;
        std::cin >> u >> v >> w;
        // debug(u, v, w + 20000000);
        Max(e[u][v], (LL) w + inf);
        // Max(e[u][v], w);
    }
    vi mchl(n + 1), mchr(n + 1);
    auto KM = [&](vvl e, vi& match, int n) -> LL {
        vl la(n + 1), lb(n + 1), pp(n + 1), vx(n + 1);
        std::vector<int> va(n + 1), vb(n + 1);
        LL delta;
        auto bfs = [&](int x) -> void {
            int a, y = 0, y1 = 0;
            std::fill(all(pp), 0);
            std::fill(all(vx), INF);
            match[y] = x;
            do {
                a = match[y], delta = INF, vb[y] = 1;
                for (int b = 1; b <= n; b++) {
                    if (!vb[b]) {
                        if (vx[b] > la[a] + lb[b] - 1ll * e[a][b]) {
                            vx[b] = la[a] + lb[b] - 1ll * e[a][b];
                            pp[b] = y;
                        }
                        if (vx[b] < delta) {
                            delta = vx[b];
                            y1 = b;
                        }
                    }
                }
                for (int b = 0; b <= n; b++) {
                    if (vb[b]) {
                        la[match[b]] -= delta;
                        lb[b] += delta;
                    } else
                        vx[b] -= delta;
                }
                y = y1;
            } while (match[y]);
            while (y) {
                match[y] = match[pp[y]];
                y = pp[y];
            }
        };
        for (int i = 1; i <= n; i++) {
            std::fill(all(vb), 0);
            bfs(i);
        }
        LL ans = 0;
        for (int i = 1; i <= n; i++) ans += e[match[i]][i];
        return ans;
    };
    LL ans = KM(e, mchl, n) - 1ll * inf * n;
    std::cout << ans << endl;
    for (int i = 1; i <= n; i++) {
        std::cout << mchl[i] << ' ';
    }


    return 0;
}
2023/4/20 16:53
加载中...