华南理工大学“三七互娱杯” G HRY and tree //并查集
题意:给一颗树,求Σ任意两点的路径中的最大值。
对于大小关系,一种常见的处理就是排序消除影响。
然后每一条边对答案的贡献就是边的两边的已存在的点的数量的乘积。
因为不存在的边权值大于该边不会对答案有贡献,而已经联通的肯定对答案有贡献。
而且树上每一条边都是割边,所以保证想法的正确性。
然后就是easy题了...这场很不友好啊,D瞎搞,这题卡LL,2e7*n(n-1)/2 ...unsigned long long可过
#include<bits/stdc++.h>
using namespace std;
#define LL long long
const LL mod = 998244353;
const int max_n = 1e6+6;
struct no{int x,y,w;};
bool operator<(const no &x,const no &y){
return x.w<y.w;
}
no a[max_n];
int fa[max_n],cnt[max_n];
int found(int x){
if(x==fa[x]) return x;
return fa[x]=found(fa[x]);
}
int main(){
int T;scanf("%d",&T);while(T--){
int n;scanf("%d",&n);for(int i=1;i<n;i++){
scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].w);
}
sort(a+1,a+n);
unsigned long long ans=0;
for(int i=1;i<=n;i++)cnt[i]=1,fa[i]=i;
for(int i=1;i<n;i++){
int fx=found(a[i].x),fy=found(a[i].y);
ans=ans+(LL)cnt[fx]*(LL)cnt[fy]*(LL)a[i].w;
fa[fx]=fy;
cnt[fy]+=cnt[fx];
}
printf("%llu\n",ans);
}
return 0;
}