链接:LeetCode685
在本问题中,有根树指满足以下条件的有向图。该树只有一个根节点,所有其他节点都是该根节点的后继。每一个节点只有一个父节点,除了根节点没有父节点。
输入一个有向图,该图由一个有着N个节点 (节点值不重复1, 2, ..., N) 的树及一条附加的边构成。附加的边的两个顶点包含在1到N中间,这条附加的边不属于树中已存在的边。
结果图是一个以边组成的二维数组。 每一个边 的元素是一对 [u, v],用以表示有向图中连接顶点 u and v和顶点的边,其中父节点u是子节点v的一个父节点。
返回一条能删除的边,使得剩下的图是有N个节点的有根树。若有多个答案,返回最后出现在给定二维数组的答案。
相关标签:并查集
这道题是之前那道Redundant Connection的拓展,那道题给的是无向图,只需要删掉组成环的最后一条边即可,归根到底就是检测环就行了。而这道题给的是有向图,整个就复杂多了,因为有多种情况存在,比如给的例子1就是无环,但是有入度为2的结点3。再比如例子2就是有环,但是没有入度为2的结点。其实还有一种情况例子没有给出,就是既有环,又有入度为2的结点。
实际上,当出现有入度为2的结点时,只需要在最后面处理这两条边即可。
代码如下:
python:
class Solution:
def findRedundantDirectedConnection(self, edges: List[List[int]]) -> List[int]:
# 是否出现入度为2的结点
outs = [edge[1] for edge in edges]
count = collections.Counter(outs)
for key in count.keys():
if count[key] == 2:
redundance = [edge for edge in edges if edge[1]==key]
edges = [edge for edge in edges if edge[1]!=key] + redundance
break
dic = {}
n = len(edges)
def find(p):
while p!=dic[p]:
p = dic[p]
return p
def union(p,q):
root1,root2 = find(p),find(q)
if root1==root2:
return True
else:
dic[root1] = root2
return False
for i in range(1,n+1):
dic[i] = i
for edge in edges:
if union(edge[0],edge[1]):
return edge