首先看一下数据范围,知道算法时间复杂度必须小于m**2。
要使图的整体权重加起来最小,那么肯定选(prim或者kru),论算法编写简单程度,肯定选prim。这题特别适合练习prim和kru,建议两种算法都使用一遍。
题目说没有重边和自环,平时写code时候需要注意这两点。
1.重边:两个点之间有两条以上的边连接
2.自环:一条线左右两端都连接一个点上
prim时间复杂度(nlogm),每个点都要遍历,并且需要用最小堆使得队列里的元素排序。
from collections import defaultdict
import heapq as pq
n, m = map(int,input().split())
edge = defaultdict(dict)
for _ in range(m):
a, b, c = map(int,input().split())
edge[a][b] = c
edge[b][a] = c
ans = 0
vis = [0]*(n+1)
qu = [ [0, 1] ]
pq.heapify(qu)
while qu:
spend, node = pq.heappop(qu)
if vis[node]:continue
vis[node] = 1
ans += spend
for nex in edge[node]:
if vis[nex]:continue
pq.heappush(qu, [edge[node][nex],nex])
print(ans)
kru时间复杂度(m),每个边都要遍历,从边中最小的两个点进行连线。
from collections import defaultdict
import heapq as pq
def find_f(x):
if vis[x] == x:
return x
vis[x] = find_f(vis[x])
return vis[x]
def kru():
ans = 0
# 把所有边都加进来排序
edge.sort()
# 初始化vis
for i in range(1, n+1):
vis[i] = i
# 开始选择最小边连接
for c, x, y in edge:
x1 = find_f(x)
y1 = find_f(y)
if x1 != y1:
vis[x1] = vis[y1]
ans += c
print(ans)
n, m = map(int,input().split())
edge = []
for _ in range(m):
a, b, c = map(int,input().split())
edge.append([c, a, b])
vis = [0]*(n+1)
kru()