[Python](PAT)1021 Deepest Root(25 分)

该博客讨论了如何在给定的无环连接图(树)中找到导致最高树高度的根节点,即最深根。介绍了输入和输出规格,并提供了样例输入和输出。文章通过广度优先搜索来解决此问题,当图的连通分量不为1时,输出错误信息及连通组件数量。Python实现代码也进行了展示。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

A graph which is connected and acyclic can be considered a tree. The hight of the tree depends on the selected root. Now you are supposed to find the root that results in a highest tree. Such a root is called the deepest root.

Input Specification:

Each input file contains one test case. For each case, the first line contains a positive integer N (≤10​4​​) which is the number of nodes, and hence the nodes are numbered from 1 to N. Then N−1 lines follow, each describes an edge by given the two adjacent nodes' numbers.

Output Specification:

For each test case, print each of the deepest roots in a line. If such a root is not unique, print them in increasing order of their numbers. In case that the given graph is not a tree, print Error: K components where K is the number of connected components in the graph.

Sample Input 1:

5
1 2
1 3
1 4
2 5

Sample Output 1:

3
4
5

Sample Input 2:

5
1 3
1 4
2 5
3 4

Sample Output 2:

Error: 2 components

题目大意

给定一张图,如果这张图的连通分量为1,则输出最深的根。最深的根即为从它开始遍历,能够遍历最多的层数的根。

如果连通分量不为1,则输出“Error: N components”,其中N为连通分量。

分析

首先用广度优先遍历判断它的节点是否只有1个,如果是直接输出1.

然后获取图信息,使用字典存储,先找出没有在输入信息中给出的点的个数,每多一个,连通分量加一。(考虑以下这个测试用例,十分坑)

35
5 20
25 22
12 28
11 26
15 29
35 33
23 6
23 6
27 5
31 27
11 16
23 23
30 11
16 19
23 31
4 17
20 9
33 6
18 17
16 6
3 3
6 10
4 16
26 33
21 32
32 7
28 1
35 34
30 8
1 15
21 23
18 1
31 23
18 3

 

输出应该是Error: 6 components。第二个结点就在输出中没有给出。

如果连通分量仅为1,则返回True和当前任意点开始的广度优先遍历的最深叶子结点。然后从这些叶子节点中随意挑选一个重新进行一次广度优先遍历,将前面得到的结果和现如今得到的最深叶子节点相加然后去重再排列,得到的就是答案。

如果连通分量不为1,则继续广度优先遍历,找出连通分量有多少,最后输出。

Python实现

def bfs(graph, start):
    global n
    count = 0
    visted = [0 for x in range(n)]
    for x in range(n):
        if x+1 not in graph:
            visted[x] = 1
            count += 1
    step = [start]
    while(count == 0):
        temp = []
        for x in step:
            visted[x-1] = 1
            for j in graph[x]:
                if visted[j-1] == 0:
                    temp.append(j)
        if len(temp) == 0:
            if 0 not in visted:
                return True, step
            else:
                break
        step = temp
    while(0 in visted):
        count += 1
        start = [x for x in graph if visted[x-1] ==0][0]
        step = [start]
        while(len(step)>0):
            temp = []
            for x in step:
                visted[x-1] = 1
                for j in graph[x]:
                    if visted[j-1] == 0:
                        temp.append(j)
            if len(temp)==0:
                if 0 not in visted:
                    return False, count
            step = temp
            
if __name__ == "__main__":
    n = int(input())
    if n==1:
        print(1)
    else:
        graph = {}
        for x in range(n-1):
            line = input().split(" ")
            start, to = int(line[0]), int(line[1])
            try:
                graph[start].append(to)
            except:
                graph[start] = [to]
            try:
                graph[to].append(start)
            except:
                graph[to] = [start]
        back = bfs(graph, start)
        if back[0]:
            another = bfs(graph, back[1][0])
            result = sorted(set(back[1] + another[1]))
            for x in result:
                print(x)
        else:
            print('Error: {} components'.format(back[1]))

用python写PAT甲级,答案全在这了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值