AC

♻️lzhh_lzhh32  •  3个月前


//kruscal
/*
	a,b两点加边,要求满足加边的权值是a到b路径上最大边权值+1 
*/
#include<iostream>
#include<algorithm>
using namespace std;
int n;
struct edge{
	int a,b;
	int len;
	bool operator < (edge e2){		//重载运算符 
		return len<e2.len;
    }
}list[20005]; 
int group[10005];
int gc[10005];		//记录连通分量点数
int find(int x){
	if(x!=group[x]){
		group[x]=find(group[x]);
	}
	return group[x];
}
int main(){
	scanf("%d",&n);		//n点 
	for(int i=0;i<n-1;i++){
		cin>>list[i].a>>list[i].b>>list[i].len;
	}
	long long ans=0;
	//完全图,每个节点度必为n-1,故遍历,找度不是n-1的点
	sort(list,list+n-1);
	for(int i=0;i<n;i++){
		group[i+1]=i+1;
		gc[i+1]=1;		//初始化为1 
	}
	for(int i=0;i<n-1;i++){		//假装进行kruskal 
		ans+=(list[i].len+1)*(gc[find(list[i].a)]*gc[find(list[i].b)]-1);		
		//边点A所在连通分量所有点和边点B所在连通分量所有点两两相连加新边,权值为当前边+1 
		//因为kruscal算法每次新加边一定是路径上的最长边 
		gc[find(list[i].b)]+=gc[find(list[i].a)];		//连通分量点数合并 
		gc[find(list[i].a)]=0;		//被合并的连通分量点数清零 
		group[find(list[i].a)]=group[find(list[i].b)];		//得先合并数量再合并编号 
	}
	
	cout<<ans<<endl;
	return 0;
}

评论:

请先登录,才能进行评论