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;
}