mirror of
https://github.com/youngyangyang04/leetcode-master.git
synced 2025-07-06 23:28:29 +08:00
@ -562,4 +562,145 @@ if __name__ == "__main__":
|
||||
### Dart
|
||||
|
||||
### C
|
||||
并查集方法一
|
||||
```c
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
// 定义边结构体,包含两个顶点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;
|
||||
}
|
||||
|
||||
```
|
||||
并查集方法二
|
||||
```c
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
// 定义边结构体,包含两个顶点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;
|
||||
}
|
||||
|
||||
```
|
||||
|
Reference in New Issue
Block a user