P10928 走廊泼水节 题解
题目大意:
给定一棵
思路:
考虑 kruskal 算法的过程:将边从小到大排序,依次扫描每条边,然后考虑合并边两端的集合。
设这两端的集合为
根据最小生成树的定义可知,我们应该将其他的边都钦定为
综上所述,我们在这棵树上执行类似 kruskal 算法的过程,先将边按从小到大排序,再依次扫描每条边,并查集维护,若两端的集合未被合并,根据乘法原理,应该连的边权和为
时间复杂度为
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 6010;
int T, n;
struct node{
int a, b, w;
bool operator <(const node &o) const {
return w < o.w;
}
}edges[N];
int p[N], sz[N];
int res;
int find(int x) {
if(p[x] != x) p[x] = find(p[x]);
return p[x];
}
int main() {
scanf("%d", &T);
while(T--) {
scanf("%d", &n);
int a, b, c;
for(int i = 1; i < n; i++) {
scanf("%d%d%d", &a, &b, &c);
edges[i] = {a, b, c};
}
sort(edges + 1, edges + n);
for(int i = 1; i <= n; i++) p[i] = i, sz[i] = 1;
res = 0;
for(int i = 1; i < n; i++) {
int a = edges[i].a, b = edges[i].b, w = edges[i].w;
a = find(a), b = find(b);
if(a != b) {
res += (w + 1) * (sz[a] * sz[b] - 1);
p[a] = b;
sz[b] += sz[a];
}
}
printf("%d\n", res);
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】