结构体和排序:
#include<cstdio>
#include<algorithm>
#define MAX 100
using namespace std;
struct node{
int fr,to,w;
}e[MAX+1];
bool cmp(const node &a,const node &b){return a.w<b.w;}
并查集:
int father[MAX+1];
int zx(int k){
if(father[k]==k)return k;
else father[k]=zx(father[k]);
return father[k];
}
void add(int a,int b){
father[zx(a)]=zx(b);
}
主程序:
int main(){
int n,m;
scanf("%d%d",&n,&m);
for(int i=1;i<=m;++i)
scanf("%d%d%d",&e[i].fr,&e[i].to,&e[i].w);
sort(e+1,e+m+1,cmp);
for(int i=1;i<=n;i++)father[i]=i;
int ans=0;
for(int i=1,j=1;j<n;i++){
if((zx(e[i].fr))==(zx(e[i].to)))continue;
//两点已经连通就不连边
else {
ans+=e[i].w;
add(e[i].fr,e[i].to);
j++;
//此时在e[i].fr和e[i].to之间连了一条边,
//用并查集合并这两点
}
}
printf("%d",ans);
return 0;
}
然而改成优先队列之后快多了。。。
#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
using namespace std;
#define M 100
#define N 50
struct E {
int w,to,from;
};
bool operator < (E a,E b) {
return a.w>b.w;
}
priority_queue<E>e;
void adde(int a,int b,int w,int num) {
E r;
r.from=a;
r.to=b;
r.w=w;
e.push(r);
}
int father[N+1];
//并查集存点是否相连
int zx(int num) {
if(num==father[num])return num;
else return father[num]=zx(father[num]);
}//并查集算祖先
void add(int a,int b) {
father[zx(a)]=father[zx(b)];
}//并查集合并两点
int main() {
int n,m;
scanf("%d%d",&n,&m);
int dt1,dt2,w;
for(int i=1; i<=m; ++i) {
scanf("%d%d%d",&dt1,&dt2,&w);
adde(dt1,dt2,w,(i<<1)-1);
adde(dt2,dt1,w,i<<1);
}
for(int i=1; i<=n; i++)father[i]=i;//并查集初始化
int ans=0;
for(int i=1; i<n; i++) {
int mine=0,minj;
E r;
while(1) {
r=e.top();
if(zx(r.from)!=zx(r.to))break;
else e.pop();
}
ans+=r.w;
add(r.from,r.to);
e.pop();
//printf("边 %d : %d <-> %d 权值为%d\n",i,r.from,r.to,r.w);
}
printf("%d",ans);
return 0;
}