文章目录
- 108.冗余连接
- 109.冗余连接II
108.冗余连接
就是对输入进来的边判断是否在一个并查集中,在的话就把这个删除了,不再就加入并查集中。
n = int(input())
father = [0] * (n+1)
def init():for i in range(n+1):father[i] = idef find(u):if father[u] != u:father[u] = find(father[u])return father[u]def isSame(u, v):u = find(u)v = find(v)return u == vdef join(u, v):u = find(u)v = find(v)if u != v:father[v] = u
init()
for i in range(n):s, t = map(int, input().split())if isSame(s, t):print(str(s)+' '+str(t))else:join(s, t)
109.冗余连接II
上一题的图是一个无向图,因此只需要把最后会导致成环的那个边删除即可。这一题则会有两种情况,第一种是出现一个结点有两个入度,这是题目所不允许出现的情况,还有一种就是和上题一样入度都为1但是出现了环的情况。
如果有一个结点入度为2,那么就一定是在这两个入的边中挑一条删除,然后看剩下的结点中是否还会出现环,如果还出现环说明删错了,应该删除另一个;反之亦然。
因此在输入边的时候需要对每一个结点的入度进行统计,所有边输入进来之后,对所有边的入的结点判断是否入度为2,是的话则把这个边拿出来。因为题目要求优先删除后加入的边,所以先把后加入的边按照上述逻辑进行判断。
如果没有入度为2的结点,那就是按照上一题的方法进行删除。
n = int(input())
father = [i for i in range(n+1)]def find(u):if father[u] != u:father[u] = find(father[u])return father[u]def isSame(u, v):u = find(u)v = find(v)return u == vdef join(u, v):if not isSame(u, v):father[v] = udef removeEdge(edges):for edge in edges():if isSame(edge[0], edge[1]):print(str(edge[0])+ ' '+str(edge[1]))returnelse:join(edge[0], edge[1])def isTreeAftherRemove(edges, index):for i in range(n):if i == index:continueif isSame(edges[i][0], edges[i][1]):return Falseelse:join(edges[i][0], edges[i][1])return Trueedges = []
inner = [0] * (n+1)
for i in range(n):edge = list(map(int, input().split()))edges.append(edge)inner[edge[1]] += 1
vec = []
for i in range(n):if inner[edges[i][1]] == 2:vec.append(i)
if vec:if isTreeAftherRemove(edges, vec[1]):print(str(edges[vec[1]][0])+' '+str(edges[vec[1]][1]))else:print(str(edges[vec[0]][0])+ ' '+str(edges[vec[0]][1]))
else:removeEdge(edges)