思路:
先考虑在哪两个结点连边:先用结点1和其他结点连边一定是最优解之一,假设有三个结点,2,3可以连边,那么有a[2] + a[3] >= 2 * 3 * c(那么a[2], a[3]至少有一个大于等于3c), 1不能和2、3连,有a[1] + a[2] < 2 * c, a[1] + a[3] < 3 * c,与前面矛盾。
综上,让所有结点按 a[1] + a[i] - i * c排序,依次跟结点1合并
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int maxn = 1e6 + 5;
int a[maxn];
int n, c;
struct Node{
int num, id;
bool operator < (const Node &u) const{
return num - id * c > u.num - u.id * c;
}
}b[maxn];
void solve(){
cin >> n >> c;
for(int i = 1; i <= n; i++){
cin >> a[i];
b[i] = {a[i], i};
}
sort(b + 2, b + n + 1);
int now = a[1];
for(int i = 2; i <= n; i++){
int num = b[i].num, id = b[i].id;
if(now + num < id * c){
cout << "No\n";
return;
}
now += num;
}
cout << "Yes\n";
}
signed main(){
ios::sync_with_stdio(0);
cin.tie(0);
int T;
cin >> T;
while(T--){
solve();
}
return 0;
}
文章描述了一个关于图论中优化连边的问题,通过比较节点权值与边权的关系,提出了一种排序并合并节点的方法,确保满足条件。C++代码展示了如何解决此问题。
562

被折叠的 条评论
为什么被折叠?



