题目:https://www.luogu.com.cn/problem/P3366
Kruskal算法:
通过边从小到大排序,若所选的边与已选的边不成环(并查集实现),则选上。
C语言:
排序用qsort(a, num, sizeof(a的类型),cmp):
_a,_b指针传入,再通过(Node*)切换格式,再通过*取值.
int cmp(void* _a, void* _b)
{
Node a = *(Node*) _a;
Node b = *(Node*) _b;
return a.weight - b.weight;
}
并查集:
find()找父节点:
int find(int fa[], int x)
{
int r = x, i = x, temp;
while (fa[r] != r)
{
r = fa[r];
}
while (i != r)
{
temp = fa[i];
fa[i] = r;
i = temp;
}
return r;
}
完整代码:
#include <stdio.h>
#include <stdlib.h>
typedef struct node
{
int from, end, weight;
}Node;
int cmp(void* _a, void* _b)
{
Node a = *(Node*) _a;
Node b = *(Node*) _b;
return a.weight - b.weight;
}
int find(int fa[], int x)
{
int r = x, i = x, temp;
while (fa[r] != r)
{
r = fa[r];
}
while (i != r)
{
temp = fa[i];
fa[i] = r;
i = temp;
}
return r;
}
void kruskal(Node edge[], int fa[], int n, int m)
{
int i = 0, tot, ans = 0, fx, fy;
tot = 0;
while (tot < n - 1 && i < m)
{
fx = find(fa, edge[i].from);
fy = find(fa, edge[i].end);
if (fx != fy)
{
fa[fx] = fy;
ans += edge[i].weight;
tot += 1;
}
i += 1;
}
if (tot < n - 1)
printf("orz");
else
printf("%d", ans);
}
int main()
{
int i, n, m, x, y, z;
Node edge[200005];
int fa[5005];
scanf("%d%d", &n, &m);
for (i = 0; i < m; i++)
{
scanf("%d%d%d", &x, &y, &z);
edge[i].from = x; edge[i].end = y; edge[i].weight = z;//只存单向
}
qsort(edge, m, sizeof(Node), cmp);
/*for (i = 0; i < m; i++)
printf("%d\n", edge[i].weight);*/
for (i = 1; i <= n; i++)
fa[i] = i;
kruskal(edge, fa, n, m);
return 0;
}
Python:
结构体数组排序:
Edg.sort(key=lambda edge: edge.weight)
#lambda edge是自己设的,是Edg[]的一个元素,并按照edg.weight从小到大排序
代码:
class Edge(object):
def __init__(self, x, y, z):
self.begin = x
self.end = y
self.weight = z
def find(x):
global fa
r = x
while fa[r] != r:
r = fa[r]
i = x
while i != r:
temp = fa[i]
fa[i] = r
i = temp
return r
def Kruskal():
global fa, Edg, n, m
tot = 0
i = 0
ans = 0
while tot < n - 1 and i < m:
fx = find(Edg[i].begin)
fy = find(Edg[i].end)
if fx != fy:
fa[fx] = fy
tot += 1
ans += Edg[i].weight
i += 1
if tot < n - 1:
print("orz")
else:
print(ans)
s = input()
n, m = s.split(' ')
n = int(n)
m = int(m)
Edg = []
for i in range(m):
s = input()
x, y, z = s.split(' ')
x = int(x)
y = int(y)
z = int(z)
Edg.append(Edge(x, y, z))
Edg.sort(key=lambda edge: edge.weight)
fa = [0 for i in range(n + 5)]
for i in range(1, n + 1):
fa[i] = i
Kruskal()