@@ -634,3 +634,66 @@ int main()
634
634
}
635
635
636
636
```
637
+ 并查集方法二
638
+ ```c
639
+ // 定义边结构体,包含两个顶点vex1和vex2以及它们之间的权重val (略,同上)
640
+ // 冒泡排序函数,用于按边的权重val不减序排序边数组(略,同上)
641
+
642
+ // 并查集的查找操作
643
+ int find(int m, int *father)
644
+ { // 如果当前节点是其自身的父节点,则直接返回该节点
645
+ // 否则递归查找其父节点的根,并将当前节点直接连接到根节点
646
+ return (m == father[m]) ? m : (father[m] = find(father[m], father)); // 路径压缩
647
+ }
648
+
649
+ // 并查集的加入集合
650
+ void Union(int m, int n, int *father)
651
+ {
652
+ int x = find(m, father);
653
+ int y = find(n, father);
654
+ if (x == y)
655
+ return; // 如果发现根相同,则说明在一个集合,不用两个节点相连直接返回
656
+ father[y] = x;
657
+ }
658
+
659
+ int main()
660
+ {
661
+ int v, e;
662
+ int v1, v2, val;
663
+ int ret = 0;
664
+
665
+ scanf("%d%d", &v, &e);
666
+ struct Edge *edg = (struct Edge *)malloc(sizeof(struct Edge) * e);
667
+ int *conne_gra = (int *)malloc(sizeof(int) * (v + 1));
668
+ // 初始化连通图数组,每个顶点初始时只与自己相连通
669
+ for (int i = 0; i <= v; ++i)
670
+ {
671
+ conne_gra[i] = i;
672
+ }
673
+ // 读取所有边的信息并存储到edg(存储所有边)数组中
674
+ for (int i = 0; i < e; ++i)
675
+ {
676
+ scanf("%d%d%d", &v1, &v2, &val);
677
+ edg[i].vex1 = v1;
678
+ edg[i].vex2 = v2;
679
+ edg[i].val = val;
680
+ }
681
+ bubblesort(edg, e); // 调用冒泡排序函数对边进行排序
682
+
683
+ // Kruskal算法的实现,通过边数组构建最小生成树
684
+ int j = 0, count = 0;
685
+ while (v > 1)
686
+ {
687
+ if (find(edg[j].vex1, conne_gra) != find(edg[j].vex2, conne_gra))
688
+ {
689
+ ret += edg[j].val; // 将当前边的权重加到最小生成树的权重中
690
+ Union(edg[j].vex1, edg[j].vex2, conne_gra);
691
+ v--;
692
+ }
693
+ j++;
694
+ }
695
+ printf("%d", ret);
696
+ return 0;
697
+ }
698
+
699
+ ```
0 commit comments