PAT甲级 1021 Deepest Root

1021 Deepest Root

题目大意:给出一个图,判断是否是一棵树,如果不是则输出连通分量个数,如果是则输出使得树最高的那个根节点。

思路:一开始我想的是先判断连通块然后再dfs求出每个节点的树高,把树高最长的节点记录下来,但是好几个超时;后来想着先求出从1开始遍历(这里别的点应该也行)离它最远的点记录下来(保存到集合中),再求出从这个集合里面第一个元素(别的也可以)dfs的结果,将距离最长的点保存下来,然后两个集合求并集就是答案。这里可以用反证法,第一个集合里的元素求dfs最大深度时必然会经过1(如果不经过则说明离1最远的不是它,就不会收入第一个集合),然后从1出发再找出最远距离即可。

注:由于我用的是python测试点3还是会超时,第一次用的cpp完全AC不是用的此种方法(一眼就知道python一定会爆掉也就懒得用了)

#测试点3超时
def DFS(index,depth):
    global n
    global max_depth
    if depth>max_depth: #若当前深度超过已有的最大深度则更新最大高度且根数组清空,放入当前节点
        max_depth=depth
        root.clear()
        root.add(index)
    elif depth==max_depth:  #若当前深度等于最大深度则将该节点加入根数组中
        root.add(index)
    visit[index]=True
    for i in range(1,n+1):
        if i in graph[index] and not visit[i]:    #若index与i之间有边且i未访问过则继续向下遍历
            DFS(i,depth+1)
    return

def DFSTraversal():
    global n
    global visit
    cnt=0
    for i in range(1,n+1):  #判断连通块的个数
        if not visit[i]:
            DFS(i,1)
            cnt+=1
    return cnt

n=int(input())
max_depth=0
root=set()
visit=[False for x in range(n+1)]
graph={}
for i in range(1,n+1):
    graph[i]=[]
for i in range(n-1):
    v1,v2=map(int,input().split())
    graph[v1].append(v2)
    graph[v2].append(v1)
cnt=DFSTraversal()
if cnt>1:
    print("Error: %d components" % cnt,end="")
else:   #由于题目明确说明是n个顶点n-1条边,所以当连通块的数量是1时一定不是环
    s1=root.copy()
    for i in root:
        visit=[False for x in range(n+1)]
        DFS(i,1)
        break
    s2=root.copy()
    for i in s2:
        s1.add(i)
    l=list(s1)
    l.sort()
    for i in l:
        print(i)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值