lahlahblog喵~

gym 102331 F. Fast Spanning Tree

lahlah·2022-02-25 22:13·215 次阅读

gym 102331 F. Fast Spanning Tree

https://codeforces.com/gym/102331/problem/F

学到许多

首先有个显然的性质,假设一条边两边的权值和分别是x,y,这条边的要求是S

x+yS 可以得到
xS2  or  yS2

我们把这条边的限制(上界)平均分别丢到x,y上,拿一个小根堆维护
x+sxy2

当启发式合并两个联通块u,v(siz[u]<siz[v])

a[v]+=a[u],把u的小根堆合并进去

然后查看堆顶,如果a[v] 堆顶的限制,那么说明v已经达到堆顶那条边的限制之一了,假设堆顶那条边是(x,y,s), 那么只需要判断如果a[x]+a[y]s就加入答案,否则把剩下的sa[x]a[y]再平均分配到x,y两个点上面的堆里,作为新的限制。

即新的上界限制是a[x]+sa[x]a[y]2,y同理

启发式合并的时间复杂度是O(nlog2n)的,然后发现每条边最多被访问logC
容易发现这样均摊下来时间复杂度是O(nlog2n+nlogC)

完全能跑

可以结合代码理解

code:

Copy
#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; }
posted @   lahlah  阅读(215)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示