CCF-201503-4-网络延时

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/AivenZhong/article/details/84704746

这题我一开始想法是暴搜。从每个边缘结点出发,都进行一次bfs,找出最大步数。但是肯定过不了全部用例,暴力搜索只拿了70。后来看别人的文章,才知道是考树的直径。
树的直径(最长路) 的详细证明

具体结论是:
从任意一点出发搜出最远的点,然后在从这个最远点开始搜,就可以搜到另一个最长路的端点,即用两遍广搜就可以找出树的最长路。

我的理解:
最长路的结点肯定在边缘嘛,但是怎么确定哪些边缘点能组成最长路呢,照以上结论,第一遍bfs,无论从哪点出发,找出的最远点(一个或多个),肯定能组成最长路的其中一个点。然后再从此点(任意一个最远点)出发找出另一个最远点,组成最长路。

python代码(100)

from queue import Queue


def bfs(start, graph):
    """返回最后一个结点和最大步数"""
    lastNode = None  # 最后一个结点
    maxStep = 0  # 最大步数
    queue = Queue()
    queue.put([start, 0])
    vis = [False for _ in range(len(graph))]
    vis[start] = True
    while not queue.empty():
        node, step = queue.get()
        lastNode = node
        maxStep = step
        for e in graph[node]:
            if not vis[e]:
                queue.put([e, step + 1])
                vis[e] = True
    return lastNode, maxStep


n, m = map(int, input().split())
# 建立邻接表
# 前n个是交换机,后m个是终端
changes = [int(v) for v in input().split()]
ends = [int(v) for v in input().split()]
graph = [[] for _ in range(n + m)]
for i in range(1, n):
    graph[i].append(changes[i - 1] - 1)
    graph[changes[i - 1] - 1].append(i)
for i in range(m):
    graph[n + i].append(ends[i] - 1)
    graph[ends[i] - 1].append(n + i)

# 一开始从任意一点出发bfs,找出最远点
longnode = bfs(0, graph)[0]

# 再从这个最远点出发bfs,找全局最远路线
maxStep = bfs(longnode, graph)[1]
print(maxStep)

猜你喜欢

转载自blog.csdn.net/AivenZhong/article/details/84704746