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)