CF1889B
给一个
个点的图,每个点 有点权 ,初始图上没有边,你可以进行如下操作若干次:
- 若
,添加一条边 。其中 表示 所在连通块的点权和, 是一个给定的常数。 问最终能否使图联通。
首先我们有一个简单的 yes
,否则 no
。
考虑优化连边过程。我们发现,合并两个连通块时,我们一定要选连通块中编号最小的点连边,因为这样在
这时注意到一个特殊的连通块:
更加形式化地:若
于是按
结论证明(参考了官方题解):
不妨令
代码:
#include<bits/stdc++.h>
#define endl '\n'
#define rep(i, s, e) for(int i = s, i##E = e; i <= i##E; ++i)
#define per(i, s, e) for(int i = s, i##E = e; i >= i##E; --i)
#define F first
#define S second
#define int ll
#define gmin(x, y) (x = min(x, y))
#define gmax(x, y) (x = max(x, y))
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef long double f128;
typedef pair<int, int> pii;
void solve() {
int n, c;
cin >> n >> c;
vector<pii> a(n + 5);
rep(i, 1, n) cin >> a[i].F, a[i].S = i;
sort(a.begin() + 2, a.begin() + n + 1, [&](pii a, pii b) {
return a.F - a.S * c > b.F - b.S * c;
});
int s = a[1].F;
rep(i, 2, n) {
// cerr << a[i].F << ' ' << a[i].S << endl;
if(a[i].S * c <= s + a[i].F) s += a[i].F;
else { cout << "No\n"; return; }
}
cout << "Yes\n";
}
signed main() {
#ifdef ONLINE_JUDGE
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
#endif
int t; cin >> t;
while(t--) solve();
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?