[小清新] [AGC028C] Min Cost Cycle

posted on 2024-05-27 05:23:21 | under | source

转化 \(+\) 鸽巢原理。

由于一条边价值是 \(\min\),且答案求的也是 \(\min\)。考虑放开限制,计入一些非法情况但不影响答案,方便计算。

对此题而言,将 \(x,y\) 取最小看成 \(x,y\) 中选恰好一个即可。

那么问题得到简化。思考一个点 \(a_i,b_i\) 是否被计入答案(对答案贡献),不妨用 \(00,01,10,11\) 表示。

注意到一个关键性质,若不存在 \(11\),则不可能同时出现 \(01,10\)

理由如下:将 \(x,y\) 的选择看成不同方向的有向边,由于这是一个环,所以必然存在一个 \(01,10\) 的交界点,这个交界点就是 \(11\) 了。同理,还能发现 \(00\)\(11\) 成对出现(虽然没啥用)。

所以合法情况只有:只选 \(a\)、只选 \(b\)、选至少一对 \(a,b\)。前两种容易解决,考虑第三种。

可以利用鸽巢原理,具体如下:让所有 \(a,b\) 一起升序排列,选取前 \(n+1\) 个记为 \(c_1\dots c_{n+1}\),此时必然存在一对 \(a,b\)

然后依次枚举去掉 \(c_{n-1},c_n,c_{n+1}\) 的方案是否满足条件,显然肯定有一种方案合法。

请注意,去掉 \(c_{n-1}\) 不一定是第三小方案,需要再枚举去掉 \(c_{n},c_{n+1}\) 然后加上 \(c_{n+2}\) 的方案。我不幸被坑了。

会影响正确性吗?不会,因为这是前 \(4\) 小的方案,而且根据先前讨论,其中必有一种合法,所以没毛病。

代码

#include<bits/stdc++.h>
using namespace std;

#define int long long
const int N = 2e5 + 5;
int n, m, res, sa, sb, ans, a[N], b[N], buc[N];
pair<int, int> c[N];

inline void add(int p) {++buc[c[p].second], res += c[p].first;}
inline void del(int p) {--buc[c[p].second], res -= c[p].first;}
inline void check() {for(int i = 1; i <= n; ++i) if(buc[i] == 2) ans = min(ans, res);}
signed main(){
	cin >> n;
	for(int i = 1; i <= n; ++i){
		scanf("%lld%lld", &a[i], &b[i]);
		sa += a[i], sb += b[i];
		c[++m] = {a[i], i}, c[++m] = {b[i], i};
	}
	ans = min(sa, sb), sort(c + 1, c + 1 + m);
	for(int i = 1; i <= n + 1; ++i) add(i);
	for(int i = n - 1; i <= n + 1; ++i) del(i), check(), add(i);
	del(n), del(n + 1), add(n + 2), check();
	cout << ans;
	return 0;
}
posted @ 2026-01-13 11:24  Zwi  阅读(0)  评论(0)    收藏  举报