C - Min Cost Cycle

智商不够,告辞


看上去毫无头绪。然而打表什么的就能发现一些性质。

我们考虑贪心,\(A\)\(B\) 塞在一起排序,发现只要前 \(n\) 个只要出现属于同一个的,或者都是 \(A\),或者都是 \(B\) 就行。

然后构造一发。

不行的情况考虑几个次优不一定合法解,能够证明把几个次优解的答案取个 min 必定会有合法解。

然后暴力判一发。证明很多地方有……菜鸡选手无限偷懒。

#include <bits/stdc++.h>

const int MAXN = 100010;
typedef long long LL;
struct node {
    int v, bel, typ;
    bool operator < (const node & b) const { return v < b.v; }
} ps[MAXN << 1];
int bak;
int A[MAXN], B[MAXN];
int n;
int main() {
    std::ios_base::sync_with_stdio(false), std::cin.tie(0);
    std::cin >> n;
    for (int i = 1; i <= n; ++i) {
        std::cin >> A[i] >> B[i];
        ps[++bak] = (node) {A[i], i, 0};
        ps[++bak] = (node) {B[i], i, 1};
    }
    std::sort(ps + 1, ps + 1 + bak);
    auto solve = [] () {
        static bool app[MAXN][2];
        memset(app, 0, sizeof app);
        int C[2] = {0, 0};
        for (int i = 1; i <= n; ++i) {
            ++C[ps[i].typ];
            app[ps[i].bel][ps[i].typ] = true;
        }
        bool can = false;
        for (int i = 1; i <= n; ++i)
            can |= app[i][0] && app[i][1];
        if (can || C[0] == n || C[1] == n) return 
            std::accumulate(ps + 1, ps + 1 + n, 0ll, [] (LL x, node a) {
                return x + a.v;
            });
        return std::numeric_limits<LL>::max();
    };
    LL ans = solve();
    std::swap(ps[n], ps[n + 1]);
    ans = std::min(ans, solve());
    std::swap(ps[n], ps[n + 2]);
    ans = std::min(ans, solve());
    std::swap(ps[n], ps[n + 2]);
    std::swap(ps[n], ps[n + 1]);
    std::swap(ps[n - 1], ps[n + 1]);
    ans = std::min(ans, solve());
    std::cout << ans << std::endl;
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/daklqw/p/12098963.html