Kruskal算法
步骤:
- 新建图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 }