一.小知识点
1.
生成树:连通图的一次遍历 所经过的边的集合以及顶点的集合 构成了一颗生成树。(对连通图不同的遍历,就用不同的生成树)
最小生成树:所有生成树中一颗边权总和最小的生成树
最大生成树:所有生成树中一颗边权总和最大的生成树
二.题目
1.prime算法:求最小生成树,选顶点
1>将边权转换为负数
2>对结构体按照边权排序,再将每个顶点的父亲设置为自己
3>判断一个结构体中 两个顶点的父节点是否相同
a.若不相同,把这两个顶点连起来
b.sum+=s[i].C;
c.num++;//当num==N-1时,跳出循环
三.代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define n 1111
ll parent[n]={0};//存储每个节点的父节点
struct s1{
ll X,Y,C=0;
}s[10010];
bool cmp(s1& a,s1& b){
return a.C<b.C;
}
ll find_father(ll x){
if(parent[x]==x) return x;
else return find_father(parent[x]);
}
int main()
{
int K;
scanf("%d",&K);
while(K--){
//TODO
ll N,M,i,j,k;
scanf("%lld %lld",&N,&M);
memset(parent,0,sizeof(parent));
for(i=1;i<=N;i++){
parent[i]=i;
}
for(i=1;i<=M;i++){
//TODO
scanf("%lld %lld",&s[i].X,&s[i].Y);
ll t;
scanf("%lld",&t);
s[i].C=-t;
}
sort(s+1,s+M+1,cmp);
ll sum=0;
ll num=0;
for(i=1;i<=M;i++){
//TODO
ll x=s[i].X;
ll y=s[i].Y;
ll x1=find_father(x);
ll y1=find_father(y);
if(x1!=y1){
parent[x1]=y1;//把最长的两条边连起来
sum-=s[i].C;
num++;
}
if(num==N-1) break;
}
printf("%lld\n", sum);
}
return 0;
}