From adc34fb2f50db35891460d482b260957b797a41c Mon Sep 17 00:00:00 2001 From: Leehouc <152672308+Leehouc@users.noreply.github.com> Date: Wed, 4 Sep 2024 17:43:22 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A00053.=E5=AF=BB=E5=AE=9D-Krusk?= =?UTF-8?q?al.mdC=E8=AF=AD=E8=A8=80=E6=96=B9=E6=B3=95=E4=BA=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/kamacoder/0053.寻宝-Kruskal.md | 63 +++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/problems/kamacoder/0053.寻宝-Kruskal.md b/problems/kamacoder/0053.寻宝-Kruskal.md index 7a693882..52724956 100644 --- a/problems/kamacoder/0053.寻宝-Kruskal.md +++ b/problems/kamacoder/0053.寻宝-Kruskal.md @@ -634,3 +634,66 @@ int main() } ``` +并查集方法二 +```c +// 定义边结构体,包含两个顶点vex1和vex2以及它们之间的权重val (略,同上) +// 冒泡排序函数,用于按边的权重val不减序排序边数组(略,同上) + +// 并查集的查找操作 +int find(int m, int *father) +{ // 如果当前节点是其自身的父节点,则直接返回该节点 + // 否则递归查找其父节点的根,并将当前节点直接连接到根节点 + return (m == father[m]) ? m : (father[m] = find(father[m], father)); // 路径压缩 +} + +// 并查集的加入集合 +void Union(int m, int n, int *father) +{ + int x = find(m, father); + int y = find(n, father); + if (x == y) + return; // 如果发现根相同,则说明在一个集合,不用两个节点相连直接返回 + father[y] = x; +} + +int main() +{ + int v, e; + int v1, v2, val; + int ret = 0; + + scanf("%d%d", &v, &e); + struct Edge *edg = (struct Edge *)malloc(sizeof(struct Edge) * e); + int *conne_gra = (int *)malloc(sizeof(int) * (v + 1)); + // 初始化连通图数组,每个顶点初始时只与自己相连通 + for (int i = 0; i <= v; ++i) + { + conne_gra[i] = i; + } + // 读取所有边的信息并存储到edg(存储所有边)数组中 + for (int i = 0; i < e; ++i) + { + scanf("%d%d%d", &v1, &v2, &val); + edg[i].vex1 = v1; + edg[i].vex2 = v2; + edg[i].val = val; + } + bubblesort(edg, e); // 调用冒泡排序函数对边进行排序 + + // Kruskal算法的实现,通过边数组构建最小生成树 + int j = 0, count = 0; + while (v > 1) + { + if (find(edg[j].vex1, conne_gra) != find(edg[j].vex2, conne_gra)) + { + ret += edg[j].val; // 将当前边的权重加到最小生成树的权重中 + Union(edg[j].vex1, edg[j].vex2, conne_gra); + v--; + } + j++; + } + printf("%d", ret); + return 0; +} + +```