专栏文章
CF2133B Villagers题解
CF2133B题解参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @mio5k1n8
- 此快照首次捕获于
- 2025/12/02 13:43 3 个月前
- 此快照最后确认于
- 2025/12/02 13:43 3 个月前
CF2133B Villagers题解
题意
一个村庄里有 个村民,每个村民有一个脾气值 。
刚开始,村庄里的每一个村民都不是朋友。
Steve 可以选择两个村民 和 ,花费 个绿宝石让他们成为朋友,并且他们的脾气值会减少 。
Steve 想要让村庄里的每一个人都成为朋友(可能有一些中间朋友)。
但是 Steve 不想让村庄经济膨胀太多,所以他想知道最少的绿宝石花费是多少。
刚开始,村庄里的每一个村民都不是朋友。
Steve 可以选择两个村民 和 ,花费 个绿宝石让他们成为朋友,并且他们的脾气值会减少 。
Steve 想要让村庄里的每一个人都成为朋友(可能有一些中间朋友)。
但是 Steve 不想让村庄经济膨胀太多,所以他想知道最少的绿宝石花费是多少。
形式化题意
有一个 个节点的无向图,刚开始有 条边。
每次连接 和 节点需要的代价是 ,之后 和 都会减少 。
求将此图变为连通图的最小代价。
每次连接 和 节点需要的代价是 ,之后 和 都会减少 。
求将此图变为连通图的最小代价。
分析
考虑贪心。每次建边的花费是 ,那每次连接的两个点一定是当前未被连接过的点权最大、次大节点。否则花费就会多出 。
这样处理过后,图中会有 个连通子图。对于每两个大小为 连通子图,连接它们的代价为 。因为在连接任意大小为 的连通子图时,其中较小 值变为 。此时连接它们的最优策略是连接两个 值为 的节点,此时代价为 。如果此时 为偶数,那么已经完成。如果 为奇数,此时还剩余一个 值最小的大小为 的连通子图,只需要将它与任意一个 值为 的节点连接即可。
这样处理过后,图中会有 个连通子图。对于每两个大小为 连通子图,连接它们的代价为 。因为在连接任意大小为 的连通子图时,其中较小 值变为 。此时连接它们的最优策略是连接两个 值为 的节点,此时代价为 。如果此时 为偶数,那么已经完成。如果 为奇数,此时还剩余一个 值最小的大小为 的连通子图,只需要将它与任意一个 值为 的节点连接即可。
代码部分
CPP#include <bits/stdc++.h>
using namespace std;
int T;
void solve(){
int n;
cin >> n;
vector <int> a(n + 1);
for(int i = 1; i <= n; i++)
cin >> a[i];
sort(a.begin() + 1, a.end());//STL内置排序
long long ans = 0;
for(int i = n; i > 0; i -= 2)//这里条件不能写 i,因为当 n 为奇数时,会出现 i = -1 的情况
ans += a[i];//连接部分
cout << ans << endl;
}
int main(){
cin >> T;
while(T--){
solve();
}
return 0;
}
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...