题目大意:
题目要我们找出最优树结构(传输时间最短的生成树),输出最优树结构的传输时间
首先来讲讲树结构的传输时间
如下图,这棵树有4层(深度为4),找出每层的最大边T(h),然后在这些最大边里面再找最大边T(max),这个T(max)就是这棵树的传输时间,说到底就是找这棵树的最大边嘛,整那么复杂概念。。。。。。。。。。
结论:树的传输时间 = 树的最大边
思路:
那么最优树结构(传输时间最短的生成树)怎么找呢?
答案:就是最小生成树
为什么?
按照Kruskal算法的思路,找最小生成树,先把边从小到大从左到右排列,然后从小到大开始找可以组成生成树的没有回路的边,最后找到的边组合起来得到最小生成树,里面存在一条最大边(设为a)。然后其他的生成树的边集,里面也存在一条最大边(设为b)。
有结论:a>=b。
假设b<a,因为b已经是最大边,b只能往左找能组成最小生成树的边,如果能找到,那么说明这个才是真正的最小生成树,但是前面说了,b的那个生成树不是最小生成树,所以假设不成立,a>=b。
所以最小生成树的最大的边一定比其他生成树的最大边要小,所以最小生成树可以有最短的传输时间,是最优树结构。
套用我自己的模板,得到最小生成树,再在里面找最大边(传输时间),输出。这题的数据量有点大,1s算不完,考试的时候python是10s限制,最后拿了100,但是现在练习题是1s限制,只能拿70分,c++的话应该可以100的。
python代码:
from queue import PriorityQueue as pQueue
# 用优先队列实现的prim算法
def prim(start, graph):
n = len(graph)
pq = pQueue() # 队列中的元素为[cost, v]形式,cost是该路径的花销, v是去往的结点
visited = [False for _ in range(n)]
t = {}
parents = [-1 for _ in range(n)]
pq.put([0, start, -1])
while len(t) < n:
# 从优先队列中找出未被确定的最短路径
minPath = pq.get()
while visited[minPath[1]]:
minPath = pq.get()
minNode = minPath[1]
visited[minNode] = True
t[minNode] = minPath[0]
parents[minNode] = minPath[2]
# 从该最短路径的结点开始找邻边,入队
for edge in graph[minPath[1]]:
if not visited[edge[0]]:
pq.put([edge[1], edge[0], minNode])
return t, parents
n = int(input())
m = int(input())
root = int(input()) - 1
graph = [[] for _ in range(n)]
for i in range(m):
v, u, t = map(int, input().split())
v -= 1
u -= 1
graph[v].append([u, t])
graph[u].append([v, t])
t, parents = prim(root, graph)
ans = 0
for k, v in t.items():
if v > ans:
ans = v
print(ans)