📅  最后修改于: 2023-12-03 14:58:36.778000             🧑  作者: Mango
在一个城市中有许多房屋和许多道路相连,城市可以表示成一个n个点m条边的无向图,假设每条道路i的长度为Li,犯罪率为Pi,现在需要修建一条新的路(就是在原有的基础上增加一条边),使得整个城市中Li*Pi之和最小,求最小值。
第1行:2个整数,分别表示城市的点数n和道路数m
第2~m+1行:每行三个整数,分别表示道路的起点、终点和犯罪率Pi
输出一行一个浮点数 表示最小Li * Pi之和,四舍五入保留三位小数。
5 6
1 2 3
1 3 4
2 3 6
2 4 8
3 4 8
4 5 7
27.000
该题目可以使用最小生成树算法来解决。首先对给定的边按照犯罪率Pi从小到大进行排序,依次加入每一条边构建一颗树,当新加入的边满足不在同一连通分量中时,将其加入答案中,并将两个连通分量合并。最终,答案即为所求。
import sys
from heapq import *
def prim():
dis = [float("inf")] * (n + 1)
st = [False] * (n + 1)
dis[1] = 0
heap = []
heappush(heap, (0, 1))
res = 0
while heap:
dist, t = heappop(heap)
if st[t]:
continue
st[t] = True
res += dist
for pair in adj[t]:
if not st[pair[0]] and pair[1] < dis[pair[0]]:
dis[pair[0]] = pair[1]
heappush(heap, (dis[pair[0]], pair[0]))
return res
n, m = map(int, input().split())
adj = [[] for _ in range(n + 1)]
for _ in range(m):
a, b, c = map(int, input().split())
adj[a].append((b, c))
adj[b].append((a, c))
adj.sort(key=lambda x: x[1])
print("{:.3f}".format(prim()))
注意代码中的变量解释和参数含义。具体请参见代码注释。