gym 102331 F. Fast Spanning Tree
https://codeforces.com/gym/102331/problem/F
学到许多
首先有个显然的性质,假设一条边两边的权值和分别是,这条边的要求是
由 可以得到
我们把这条边的限制(上界)平均分别丢到上,拿一个小根堆维护
当启发式合并两个联通块时
,把的小根堆合并进去
然后查看堆顶,如果 堆顶的限制,那么说明已经达到堆顶那条边的限制之一了,假设堆顶那条边是, 那么只需要判断如果就加入答案,否则把剩下的再平均分配到两个点上面的堆里,作为新的限制。
即新的上界限制是,同理
启发式合并的时间复杂度是的,然后发现每条边最多被访问次
容易发现这样均摊下来时间复杂度是的
完全能跑
可以结合代码理解
code:
#include<bits/stdc++.h>
#define N 400050
#define fi first
#define se second
using namespace std;
const int inf = 1e9;
struct E {
int u, v, c;
} e[N << 1];
int fa[N], a[N], ans[N], gs;
priority_queue<pair<int, int> > q[N];
priority_queue<int> ok;
int get(int x) {
return x == fa[x]? x : (fa[x] = get(fa[x]));
}
void add(int i) { //printf("* %d\n", i);
int x = get(e[i].u), y = get(e[i].v);
if(x == y) return ;
if(a[x] + a[y] >= e[i].c) {
ok.push(- i);
return ;
}
int o = (e[i].c - a[x] - a[y] + 1) / 2;
q[x].push(make_pair(-(a[x] + o), i));
q[y].push(make_pair(-(a[y] + o), i));
}
void merge(int u, int v, int i) {
// printf("%d %d %d\n", u, v, i);
u = get(u), v = get(v);
if(u == v) return ;
ans[++ gs] = i;
if(q[u].size() > q[v].size()) swap(u, v);
fa[u] = v; a[v] = a[u] + a[v];
if(a[v] > inf) a[v] = inf;
while(q[u].size()) {
auto x = q[u].top(); q[u].pop();
if(-x.fi <= a[v]) add(x.se);
else q[v].push(x);
}
while(q[v].size()) {
auto x = q[v].top(); q[v].pop();
// printf("%d %d\n", x.fi, x.se);
if(-x.fi <= a[v]) add(x.se);
else {
q[v].push(x);
break;
}
}
}
int n, m;
int main() {
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; i ++) scanf("%d", &a[i]);
for(int i = 1; i <= n; i ++) fa[i] = i;
for(int i = 1; i <= m; i ++) {
scanf("%d%d%d", &e[i].u, &e[i].v, &e[i].c);
add(i);
}
while(ok.size()) {
int i = -ok.top(); ok.pop();
merge(e[i].u, e[i].v, i);
}
//sort(ans + 1, ans + 1 + gs);
printf("%d\n", gs);
for(int i = 1; i <= gs; i ++) printf("%d ", ans[i]);
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!