Skip to content

Commit 72736bb

Browse files
Merge pull request #2718 from Leehouc/master
添加 0053.寻宝-Kruskal.md C语言
2 parents 03eb883 + d3ad53e commit 72736bb

File tree

1 file changed

+141
-0
lines changed

1 file changed

+141
-0
lines changed

problems/kamacoder/0053.寻宝-Kruskal.md

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -562,4 +562,145 @@ if __name__ == "__main__":
562562
### Dart
563563

564564
### C
565+
并查集方法一
566+
```c
567+
#include <stdio.h>
568+
#include <stdlib.h>
569+
570+
// 定义边结构体,包含两个顶点vex1和vex2以及它们之间的权重val
571+
struct Edge
572+
{
573+
int vex1, vex2, val;
574+
};
575+
576+
// 冒泡排序函数,用于按边的权重val不减序排序边数组
577+
void bubblesort(struct Edge *a, int numsize)
578+
{
579+
for (int i = 0; i < numsize - 1; ++i)
580+
{
581+
582+
for (int j = 0; j < numsize - i - 1; ++j)
583+
{
584+
if (a[j].val > a[j + 1].val)
585+
{
586+
struct Edge temp = a[j];
587+
a[j] = a[j + 1];
588+
a[j + 1] = temp;
589+
}
590+
}
591+
}
592+
}
593+
594+
int main()
595+
{
596+
int v, e;
597+
int v1, v2, val;
598+
int ret = 0;
599+
600+
scanf("%d%d", &v, &e);
601+
struct Edge *edg = (struct Edge *)malloc(sizeof(struct Edge) * e);
602+
int *conne_gra = (int *)malloc(sizeof(int) * (v + 1));
603+
604+
// 初始化连通图数组,每个顶点初始时只与自己相连通
605+
for (int i = 0; i <= v; ++i)
606+
{
607+
conne_gra[i] = i;
608+
}
609+
610+
// 读取所有边的信息并存储到edg(存储所有边的)数组中
611+
for (int i = 0; i < e; ++i)
612+
{
613+
scanf("%d%d%d", &v1, &v2, &val);
614+
edg[i].vex1 = v1;
615+
edg[i].vex2 = v2;
616+
edg[i].val = val;
617+
}
618+
bubblesort(edg, e); // 调用冒泡排序函数对边进行排序
619+
620+
// 遍历所有边,执行Kruskal算法来找到最小生成树
621+
for (int i = 0; i < e; ++i)
622+
{
623+
if (conne_gra[edg[i].vex1] != conne_gra[edg[i].vex2])
624+
{ // 如果当前边的两个顶点不在同一个连通分量中
625+
int tmp1 = conne_gra[edg[i].vex1], tmp2 = conne_gra[edg[i].vex2];
626+
for (int k = 1; k <= v; ++k)
627+
{ // 将所有属于tmp2的顶点合并到tmp1的连通分量中
628+
if (conne_gra[k] == tmp2)
629+
conne_gra[k] = tmp1;
630+
}
631+
ret += edg[i].val; // 将当前边的权重加到最小生成树的权重中
632+
}
633+
}
634+
printf("%d", ret);
635+
return 0;
636+
}
637+
638+
```
639+
并查集方法二
640+
```c
641+
#include <stdio.h>
642+
#include <stdlib.h>
565643
644+
// 定义边结构体,包含两个顶点vex1和vex2以及它们之间的权重val (略,同上)
645+
// 冒泡排序函数,用于按边的权重val不减序排序边数组(略,同上)
646+
647+
// 并查集的查找操作
648+
int find(int m, int *father)
649+
{ // 如果当前节点是其自身的父节点,则直接返回该节点
650+
// 否则递归查找其父节点的根,并将当前节点直接连接到根节点
651+
return (m == father[m]) ? m : (father[m] = find(father[m], father)); // 路径压缩
652+
}
653+
654+
// 并查集的加入集合
655+
void Union(int m, int n, int *father)
656+
{
657+
int x = find(m, father);
658+
int y = find(n, father);
659+
if (x == y)
660+
return; // 如果发现根相同,则说明在一个集合,不用两个节点相连直接返回
661+
father[y] = x;
662+
}
663+
664+
int main()
665+
{
666+
int v, e;
667+
int v1, v2, val;
668+
int ret = 0;
669+
670+
scanf("%d%d", &v, &e);
671+
struct Edge *edg = (struct Edge *)malloc(sizeof(struct Edge) * e);
672+
int *conne_gra = (int *)malloc(sizeof(int) * (v + 1));
673+
674+
// 初始化连通图数组,每个顶点初始时只与自己相连通
675+
for (int i = 0; i <= v; ++i)
676+
{
677+
conne_gra[i] = i;
678+
}
679+
// 读取所有边的信息并存储到edg(存储所有边的)数组中
680+
for (int i = 0; i < e; ++i)
681+
{
682+
scanf("%d%d%d", &v1, &v2, &val);
683+
edg[i].vex1 = v1;
684+
edg[i].vex2 = v2;
685+
edg[i].val = val;
686+
}
687+
688+
bubblesort(edg, e); // 调用冒泡排序函数对边进行排序
689+
690+
// Kruskal算法的实现,通过边数组构建最小生成树
691+
int j = 0, count = 0;
692+
while (v > 1)
693+
{
694+
if (find(edg[j].vex1, conne_gra) != find(edg[j].vex2, conne_gra))
695+
{
696+
ret += edg[j].val; // 将当前边的权重加到最小生成树的权重中
697+
Union(edg[j].vex1, edg[j].vex2, conne_gra);
698+
v--;
699+
}
700+
j++;
701+
}
702+
printf("%d", ret);
703+
return 0;
704+
}
705+
706+
```

0 commit comments

Comments
 (0)