最小生成树 计算带权无向连通图G的最小生成树。输入格式: 第一行两个整数:N(1≤N<300000),表示结点集{1,2,3N};M(0 ≤ M≤600000)表示边的条数。 接下来M行,每行表示一条带权的边,用3个整数uvc表示,分别表示一条边的两个端点以及其权值(权值范围0<c<10°)输出格式: 一个整数,表示G的最小生成树的边权之和。 【样例输入】 5101231371491552362482 5434 93 57452 【样例输出】 15
时间: 2024-02-19 17:02:21 浏览: 73
这是一个经典的最小生成树问题,可以使用Kruskal或Prim算法求解。下面是Prim算法的实现:
```python
import heapq
# Prim算法
def prim(n, edges):
visited = [False] * n
h = [(0, 0)] # (dist, u)
res = 0
while h:
d, u = heapq.heappop(h)
if visited[u]:
continue
visited[u] = True
res += d
for v, w in edges[u]:
if not visited[v]:
heapq.heappush(h, (w, v))
return res
# 读入数据
n, m = map(int, input().split())
edges = [[] for _ in range(n)]
for i in range(m):
u, v, w = map(int, input().split())
edges[u-1].append((v-1, w))
edges[v-1].append((u-1, w))
# 求解最小生成树
print(prim(n, edges))
```
其中,Prim算法主要包含两个部分:节点的选择和边的维护。节点的选择采用贪心策略,即每次选择与已经选中的节点距离最近的节点。边的维护可以使用堆实现,其中堆中存储的是`(dist, u)`元组,表示距离已经选中的节点的距离为`dist`的节点`u`。在每次从堆中弹出元素时,需要判断该节点是否已经被访问过,如果已经被访问过,则忽略该节点。如果该节点没有被访问过,则将该节点标记为已访问,并将与该节点相邻的未访问节点加入堆中。
阅读全文