步骤:
- 新建图G,G中拥有原图中相同的节点,但没有边
- 将原图中所有的边按权值从小到大排序
- 从权值最小的边开始,如果这条边连接的两个节点于图G中不在同一个连通分量中,则添加这条边到图G中
- 重复3,直至图G中所有的节点都在同一个连通分量中


1 #include<bits/stdc++.h>
2
3 using namespace std;
4
5 struct node{
6 int x,y,w;
7 }a[200002];
8
9 int f[200002];
10
11 bool cmp(node xx,node yy){//结构体排序
12 return xx.w<yy.w;
13 }
14
15 int find(int x){
16 //并查集说白了就是找父结点的过程,同一个父节点即同一个区间
17 if(x==f[x]) return x;
18 f[x]=find(f[x]);
19 return f[x];
20 }
21
22 int main(){
23 int n,k,m=0;
24 scanf("%d",&n);
25 for(int i=1;i<=n;i++){
26 f[i]=i;
27 for(int j=1;j<=n;j++)
28 {
29 scanf("%d",&k);
30 if(j>i){
31 //读入时加一个判断就可以了,不需要读那么多
32 m++;
33 a[m].x=i;a[m].y=j;a[m].w=k;
34 }
35 }
36 }
37 sort(a+1,a+m+1,cmp);//排序
38 int ans=0,p=1;
39 for(int i=1;i<=m;i++){
40 if(find(a[i].x)!=find(a[i].y)){
41 //如果不在一个集合
42 ans+=a[i].w;
43 f[find(a[i].x)]=a[i].y;
44 //合并两个节点
45 p++;
46 if(p==n) break;
47 }
48 }
49 cout<<ans;
50 return 0;
51 }