代码随想录算法训练营第58天 | 并查集应用类

108.冗余连接
https://kamacoder.com/problempage.php?pid=1181
代码随想录
https://www.programmercarl.com/kamacoder/0108.冗余连接.html#思路

108.冗余连接

  • 在加入边之前;判断是否在一个集合;如果不在一个集合内,加入边;如果在一个集合内,就不加入(否则就会出现环)

  • 建立类 直接调用类

    点击查看代码
    class unionfind:
    	def __init__(self,size):
    		self.root = [i for i in range(size)]
    	def find(self,u):
    		if u != self.root[u]:
    			self.root[u] = self.find(self.root[u])
    		return self.root[u]
    	def join(self,u,v):
    		u = self.find(u)
    		v = self.find(v)
    		if u==v:
    			return
    		self.root[v] = u
    	def issame(self,u,v):
    		u = self.find(u)
    		v = self.find(v)
    		return u==v
    def main():
    	n = int(input())
    	uf = unionfind(n+1)
    	for _ in range(n):
    		s,t = map(int,input().split())
    		if uf.issame(s,t):
    		   print(str(s)+" "+str(t))
    		else:
    			uf.join(s,t)
    if __name__ == '__main__':
    	main()
    

    109.冗余连接2

    • 入度为2的节点
      • 情况一:两个边都能删除 删除顺序靠后的边;
      • 情况二:需要判断哪一条边
        • 删一条边后是否是有向树
    • 没有入度为2的点 说明图中已经有环:删掉构成环的边
    • 步骤:
      • 输入边 收集对应的入度个数
      • 如果找到为2的边:反向
        • 判断删除哪条边:如果删除该边有环 则返回false
      • 如果没有入度为2的边 遍历每条边 找到环则删除
    点击查看代码
    class unionfind:
    	def __init__(self,size):
    		self.root = [i for i in range(size)]
    	def find(self,u):
    		if u != self.root[u]:
    			self.root[u] = self.find(self.root[u])
    		return self.root[u]
    	def join(self,u,v):
    		u = self.find(u)
    		v = self.find(v)
    		if u==v:
    			return
    		self.root[v] = u
    	def issame(self,u,v):
    		u = self.find(u)
    		v = self.find(v)
    		return u==v
    
    def getremove(edges):
    	uf = unionfind(len(edges)+1)
    	for i in edges:
    		if uf.issame(i[0],i[1]):
    			print(str(i[0])+" "+str(i[1]))
    			return
    		else:
    			uf.join(i[0],i[1])
    
    def istreeafterremove(edges,delete):
    	uf = unionfind(len(edges)+1)
    	for i in range(len(edges)):
    		if i==delete:
    			continue
    		if uf.issame(edges[i][0],edges[i][1]):
    			return False
    		uf.join(edges[i][0],edges[i][1])
    	return True
    
    def main():
    	n = int(input())
    	indegree = [0]*(n+1)
    	edges = []
    	for _ in range(n):
    		s,t = map(int,input().split())
    		edges.append([s,t])
    		indegree[t]+=1
    	vec = []
    	for i in range(n-1,-1,-1):
    		if indegree[edges[i][1]]==2:
    			vec.append(i)
    	if len(vec)>0:
    		if istreeafterremove(edges,vec[0]):
    			print(str(edges[vec[0]][0])+" "+str(edges[vec[0]][1]))
    		else:
    			print(str(edges[vec[1]][0])+" "+str(edges[vec[1]][1]))
    		return
    	else:
    		getremove(edges)
    if __name__ == '__main__':
    	main()
    
posted @ 2024-08-06 11:41  哆啦**  阅读(1)  评论(0编辑  收藏  举报