打卡Day56
1. 108. 冗余连接
怎么判断边冗余。从前往后遍历每一条边,判断边的两个节点是否在同一个集合,如果不在,则将它们加入集合,如果在,说明这两个点已经连在一起了,则这条边冗余。
def find(u):
if father[u] == u:
return u
father[u] = find(father[u])
return father[u]
def issame(u,v):
u = find(u)
v = find(v)
return u == v
#u <- v
def joinside(u,v):
u = find(u)
v = find(v)
if u == v:
return
else:
father[v] = u
n = int(input())
res = [0,0]
father = [0] * (n+1)
#初始化
for i in range(n+1):
father[i] = i
for _ in range(n):
s,t = map(int,input().split())
if issame(s,t):
#同根,则冗余
res[0] = s
res[1] = t
else:
joinside(s,t)
print(f"{res[0]} {res[1]}")
2. 109. 冗余连接II
题目链接:109. 冗余连接II
文档讲解: 代码随想录
这道题和上一题的区别是,是有向图。本题的本质是,有一个有向图,是由一颗有向树+一条有向边组成的。有向树的性质,只有根节点入度为0,其他节点入度为1,因为该树除了根节点外的每个节点都有且只有一个父节点,而根节点没有父节点。有三种情况,第一种情况,找到入度为2的点,删哪条都一样,那么删掉一条指向该节点的边就行了。第二种情况,只能删特定的一条边,需要判断删除哪一条边后本图能够成为有向树。第三种情况,如果没有入度为2的点,说明图中有环,删除构成环的边就可以了。
#初始化father数组
def ini(father,n):
for i in range(1,n+1):
father[i] = i
def find(u,father):
if father[u] == u:
return u
father[u] = find(father[u],father)
return father[u]
def issame(u,v,father):
u = find(u,father)
v = find(v,father)
return u == v
#u->v
def joinside(u,v,father):
u = find(u,father)
v = find(v,father)
if u == v:
return
father[u] = v
#判断删掉一边后是否是树
def istree(father,n,nodes,delnode):
ini(father,n)
for i in range(n):
if i == delnode:
continue
if issame(nodes[i][0],nodes[i][1],father):
#有环,不是树
return False
joinside(nodes[i][0],nodes[i][1],father)
return True
#有环删掉
def getremove(father,n,nodes):
ini(father,n)
for i in range(n):
if issame(nodes[i][0],nodes[i][1],father):
print(f"{nodes[i][0]} {nodes[i][1]}")
return
joinside(nodes[i][0],nodes[i][1],father)
def main():
n = int(input())
father = [0] * (n+1)
nodes = []
#统计入度
indegree = [0] * (n+1)
for _ in range(n):
s,t = map(int,input().split())
indegree[t] += 1
nodes.append((s,t))
#找入度为2的点
vec = []
for i in range(n-1,-1,-1):
if indegree[nodes[i][1]] == 2:
vec.append(i)
#情况一、二
if len(vec) > 0:
if istree(father,n,nodes,vec[0]):
print(f"{nodes[vec[0]][0]} {nodes[vec[0]][1]}")
else:
print(f"{nodes[vec[1]][0]} {nodes[vec[1]][1]}")
return
#1情况三
getremove(father,n,nodes)
if __name__ == "__main__":
main()