题目大意:给出一个图,判断是否是一棵树,如果不是则输出连通分量个数,如果是则输出使得树最高的那个根节点。
思路:一开始我想的是先判断连通块然后再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条)