From 74097173006cabb33f75e331e0aa05256210c13f Mon Sep 17 00:00:00 2001 From: Leehouc <152672308+Leehouc@users.noreply.github.com> Date: Wed, 4 Sep 2024 17:38:10 +0800 Subject: [PATCH 1/4] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=200053.=E5=AF=BB?= =?UTF-8?q?=E5=AE=9D-Kruskal.mdC=E8=AF=AD=E8=A8=80=E6=96=B9=E6=B3=95?= =?UTF-8?q?=E4=B8=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/kamacoder/0053.寻宝-Kruskal.md | 71 +++++++++++++++++++++++ 1 file changed, 71 insertions(+) diff --git a/problems/kamacoder/0053.寻宝-Kruskal.md b/problems/kamacoder/0053.寻宝-Kruskal.md index fb816fb1..7a693882 100644 --- a/problems/kamacoder/0053.寻宝-Kruskal.md +++ b/problems/kamacoder/0053.寻宝-Kruskal.md @@ -562,4 +562,75 @@ if __name__ == "__main__": ### Dart ### C +并查集方法一 +```c +// 定义边结构体,包含两个顶点vex1和vex2以及它们之间的权重val +struct Edge +{ + int vex1, vex2, val; +}; + +// 冒泡排序函数,用于按边的权重val不减序排序边数组 +void bubblesort(struct Edge *a, int numsize) +{ + for (int i = 0; i < numsize - 1; ++i) + { + + for (int j = 0; j < numsize - i - 1; ++j) + { + if (a[j].val > a[j + 1].val) + { + struct Edge temp = a[j]; + a[j] = a[j + 1]; + a[j + 1] = temp; + } + } + } +} + +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算法来找到最小生成树 + for (int i = 0; i < e; ++i) + { + if (conne_gra[edg[i].vex1] != conne_gra[edg[i].vex2]) + { // 如果当前边的两个顶点不在同一个连通分量中 + int tmp1 = conne_gra[edg[i].vex1], tmp2 = conne_gra[edg[i].vex2]; + for (int k = 1; k <= v; ++k) + { // 将所有属于tmp2的顶点合并到tmp1的连通分量中 + if (conne_gra[k] == tmp2) + conne_gra[k] = tmp1; + } + ret += edg[i].val; // 将当前边的权重加到最小生成树的权重中 + } + } + printf("%d", ret); + return 0; +} + +``` 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 2/4] =?UTF-8?q?=E6=B7=BB=E5=8A=A00053.=E5=AF=BB=E5=AE=9D-K?= =?UTF-8?q?ruskal.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; +} + +``` From fd0f78cac25912fd6e9eff6cfa51244a1e60fd6c Mon Sep 17 00:00:00 2001 From: Leehouc <152672308+Leehouc@users.noreply.github.com> Date: Wed, 4 Sep 2024 17:45:00 +0800 Subject: [PATCH 3/4] =?UTF-8?q?=E5=8A=A0=E5=A4=B4=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/kamacoder/0053.寻宝-Kruskal.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/problems/kamacoder/0053.寻宝-Kruskal.md b/problems/kamacoder/0053.寻宝-Kruskal.md index 52724956..7f5ec3c4 100644 --- a/problems/kamacoder/0053.寻宝-Kruskal.md +++ b/problems/kamacoder/0053.寻宝-Kruskal.md @@ -564,6 +564,8 @@ if __name__ == "__main__": ### C 并查集方法一 ```c +#include +#include // 定义边结构体,包含两个顶点vex1和vex2以及它们之间的权重val struct Edge @@ -636,6 +638,9 @@ int main() ``` 并查集方法二 ```c +#include +#include + // 定义边结构体,包含两个顶点vex1和vex2以及它们之间的权重val (略,同上) // 冒泡排序函数,用于按边的权重val不减序排序边数组(略,同上) From d3ad53e4f2157158276ec84b3704d4ce7858b25c Mon Sep 17 00:00:00 2001 From: Leehouc <152672308+Leehouc@users.noreply.github.com> Date: Wed, 4 Sep 2024 17:51:11 +0800 Subject: [PATCH 4/4] =?UTF-8?q?Update=200053.=E5=AF=BB=E5=AE=9D-Kruskal.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/kamacoder/0053.寻宝-Kruskal.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/problems/kamacoder/0053.寻宝-Kruskal.md b/problems/kamacoder/0053.寻宝-Kruskal.md index 7f5ec3c4..cb24fd17 100644 --- a/problems/kamacoder/0053.寻宝-Kruskal.md +++ b/problems/kamacoder/0053.寻宝-Kruskal.md @@ -607,7 +607,7 @@ int main() conne_gra[i] = i; } - // 读取所有边的信息并存储到edg(存储所有边)数组中 + // 读取所有边的信息并存储到edg(存储所有边的)数组中 for (int i = 0; i < e; ++i) { scanf("%d%d%d", &v1, &v2, &val); @@ -670,12 +670,13 @@ int main() 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(存储所有边)数组中 + // 读取所有边的信息并存储到edg(存储所有边的)数组中 for (int i = 0; i < e; ++i) { scanf("%d%d%d", &v1, &v2, &val); @@ -683,6 +684,7 @@ int main() edg[i].vex2 = v2; edg[i].val = val; } + bubblesort(edg, e); // 调用冒泡排序函数对边进行排序 // Kruskal算法的实现,通过边数组构建最小生成树