算法工程师第四十八天(108.冗余连接 109.冗余连接II)

2024-08-28 02:36

本文主要是介绍算法工程师第四十八天(108.冗余连接 109.冗余连接II),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

参考文献 代码随想录

一、冗余连接

题目描述

树可以看成是一个图(拥有 n 个节点和 n - 1 条边的连通无环无向图)。 

现给定一个拥有 n 个节点(节点标号是从 1 到 n)和 n 条边的连通无向图,请找出一条可以删除的边,删除后图可以变成一棵树。

输入描述

第一行包含一个整数 N,表示图的节点个数和边的个数。

后续 N 行,每行包含两个整数 s 和 t,表示图中 s 和 t 之间有一条边。

输出描述

输出一条可以删除的边。如果有多个答案,请删除标准输入中最后出现的那条边。

输入示例
3
1 2
2 3
1 3
输出示例
1 3
提示信息

图中的 1 2,2 3,1 3 等三条边在删除后都能使原图变为一棵合法的树。但是 1 3 由于是标准输出里最后出现的那条边,所以输出结果为 1 3

数据范围:

1 <= N <= 1000.

问题分析

这道题目也是并查集基础题目。

这里我依然降调一下,并查集可以解决什么问题:两个节点是否在一个集合,也可以将两个节点添加到一个集合中。

如果还不了解并查集,可以看这里:并查集理论基础

我们再来看一下这道题目。

题目说是无向图,返回一条可以删去的边,使得结果图是一个有着N个节点的树(即:只有一个根节点)。

如果有多个答案,则返回二维数组中最后出现的边。

那么我们就可以从前向后遍历每一条边(因为优先让前面的边连上),边的两个节点如果不在同一个集合,就加入集合(即:同一个根节点)。

如图所示:

节点A 和节点 B 不在同一个集合,那么就可以将两个 节点连在一起。

如果边的两个节点已经出现在同一个集合里,说明着边的两个节点已经连在一起了,再加入这条边一定就出现环了。

如图所示:

已经判断 节点A 和 节点B 在在同一个集合(同一个根),如果将 节点A 和 节点B 连在一起就一定会出现环。

这个思路清晰之后,代码就很好写了。

class UnionFind():def __init__(self, length):self.fa = list(range(length + 1))  # 初始化,默认自己为自己的父亲def find(self, x):if x != self.fa[x]: self.fa[x] = self.find(self.fa[x])  # 路基压缩return self.fa[x]def is_same(self, u, v):return self.find(u) == self.find(v)  # 查def join(self, u, v):fa_u = self.find(u)fa_v = self.find(v)  # 并if fa_v != fa_u:self.fa[fa_u] = fa_v# 不要形成环
n = int(input())
uf = UnionFind(n)
for i in range(n):u, v = map(int, input().split())if uf.is_same(u, v):print(u, v)else:uf.join(u, v)

二、冗余连接II

题目描述

有一种有向树,该树只有一个根节点,所有其他节点都是该根节点的后继。该树除了根节点之外的每一个节点都有且只有一个父节点,而根节点没有父节点。有向树拥有 n 个节点和 n - 1 条边。如图: 

现在有一个有向图,有向图是在有向树中的两个没有直接链接的节点中间添加一条有向边。如图:

输入一个有向图,该图由一个有着 n 个节点(节点编号 从 1 到 n),n 条边,请返回一条可以删除的边,使得删除该条边之后该有向图可以被当作一颗有向树。

输入描述

第一行输入一个整数 N,表示有向图中节点和边的个数。 

后续 N 行,每行输入两个整数 s 和 t,代表这是 s 节点连接并指向 t 节点的单向边

输出描述

输出一条可以删除的边,若有多条边可以删除,请输出标准输入中最后出现的一条边。

输入示例
3
1 2
1 3
2 3
输出示例
2 3
提示信息

在删除 2 3 后有向图可以变为一棵合法的有向树,所以输出 2 3

数据范围:

1 <= N <= 1000.

# 有向图要构成树有两个条件
# 1。每个节点入度必须为1
# 2。不可以形成环
# 删除一条边没有形成环,删除最后一边(情况1)
# 删除一条边以后可能形成环,必须判断(情况2)
# 本身可能是环,需要删除(情况3)
class Union_search:def __init__(self, M):self.father = [i for i in range(M + 1)]def find(self, u):if u != self.father[u]:self.father[u] = self.find(self.father[u])return self.father[u]def is_same(self, u, v):f_u = self.find(u)f_v = self.find(v)return f_u == f_vdef join(self, u, v):f_u = self.find(u)f_v = self.find(v)if f_u != f_v:self.father[f_v] = f_udef find_cycle(M, sides):  # 删除环us = Union_search(M)for x, y in sides:if us.is_same(x, y):  # 如果在同一个集合里return x, yus.join(x, y)return Nonedef is_cycle_after_remove(M, del_side, sides):us = Union_search(M)  # 初始化, m是边for x, y in sides:if x == del_side[0] and y == del_side[1]:  # 如果等于我们要删除的那条边的话,就跳过continueif us.is_same(x, y):  # 如果删除del_side之后,还存在环那么,直接返回Truereturn Trueus.join(x, y)    # 不存在环return False  # 删除了之后,不存在环def main():M = int(input())sides = []  # 存放的是边in_degree = [0] * (M + 1)for i in range(M):sides.append(list(map(int, input().split())))in_degree[sides[i][1]] += 1  # 统计每个节点的入度情况# 倒叙遍历入度为2的点,并将进入这些点的边加入vecvec = []for i in range(M - 1, -1, -1):  # 倒序遍历if in_degree[sides[i][1]] == 2:   # 统计出入度为2的是哪些边vec.append(sides[i])if vec:# 正序遍历vec列表,试图删除for i in range(len(vec)):if not is_cycle_after_remove(M, vec[i], sides):  # M是节点数量, vec[i]那些边参与入度为2的节点,然后删除的是靠后的那条边print(vec[i][0], vec[i][1])returnelse:# 如果没有找到可删除的边,试图验证是否形成环?x, y = find_cycle(M, sides)print(x, y)if __name__ == "__main__":main()

这篇关于算法工程师第四十八天(108.冗余连接 109.冗余连接II)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1113479

相关文章

Python中的随机森林算法与实战

《Python中的随机森林算法与实战》本文详细介绍了随机森林算法,包括其原理、实现步骤、分类和回归案例,并讨论了其优点和缺点,通过面向对象编程实现了一个简单的随机森林模型,并应用于鸢尾花分类和波士顿房... 目录1、随机森林算法概述2、随机森林的原理3、实现步骤4、分类案例:使用随机森林预测鸢尾花品种4.1

Xshell远程连接失败以及解决方案

《Xshell远程连接失败以及解决方案》本文介绍了在Windows11家庭版和CentOS系统中解决Xshell无法连接远程服务器问题的步骤,在Windows11家庭版中,需要通过设置添加SSH功能并... 目录一.问题描述二.原因分析及解决办法2.1添加ssh功能2.2 在Windows中开启ssh服务2

Redis连接失败:客户端IP不在白名单中的问题分析与解决方案

《Redis连接失败:客户端IP不在白名单中的问题分析与解决方案》在现代分布式系统中,Redis作为一种高性能的内存数据库,被广泛应用于缓存、消息队列、会话存储等场景,然而,在实际使用过程中,我们可能... 目录一、问题背景二、错误分析1. 错误信息解读2. 根本原因三、解决方案1. 将客户端IP添加到Re

Mysql 中的多表连接和连接类型详解

《Mysql中的多表连接和连接类型详解》这篇文章详细介绍了MySQL中的多表连接及其各种类型,包括内连接、左连接、右连接、全外连接、自连接和交叉连接,通过这些连接方式,可以将分散在不同表中的相关数据... 目录什么是多表连接?1. 内连接(INNER JOIN)2. 左连接(LEFT JOIN 或 LEFT

Spring Boot实现多数据源连接和切换的解决方案

《SpringBoot实现多数据源连接和切换的解决方案》文章介绍了在SpringBoot中实现多数据源连接和切换的几种方案,并详细描述了一个使用AbstractRoutingDataSource的实... 目录前言一、多数据源配置与切换方案二、实现步骤总结前言在 Spring Boot 中实现多数据源连接

QT实现TCP客户端自动连接

《QT实现TCP客户端自动连接》这篇文章主要为大家详细介绍了QT中一个TCP客户端自动连接的测试模型,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录版本 1:没有取消按钮 测试效果测试代码版本 2:有取消按钮测试效果测试代码版本 1:没有取消按钮 测试效果缺陷:无法手动停

不懂推荐算法也能设计推荐系统

本文以商业化应用推荐为例,告诉我们不懂推荐算法的产品,也能从产品侧出发, 设计出一款不错的推荐系统。 相信很多新手产品,看到算法二字,多是懵圈的。 什么排序算法、最短路径等都是相对传统的算法(注:传统是指科班出身的产品都会接触过)。但对于推荐算法,多数产品对着网上搜到的资源,都会无从下手。特别当某些推荐算法 和 “AI”扯上关系后,更是加大了理解的难度。 但,不了解推荐算法,就无法做推荐系

W外链微信推广短连接怎么做?

制作微信推广链接的难点分析 一、内容创作难度 制作微信推广链接时,首先需要创作有吸引力的内容。这不仅要求内容本身有趣、有价值,还要能够激起人们的分享欲望。对于许多企业和个人来说,尤其是那些缺乏创意和写作能力的人来说,这是制作微信推广链接的一大难点。 二、精准定位难度 微信用户群体庞大,不同用户的需求和兴趣各异。因此,制作推广链接时需要精准定位目标受众,以便更有效地吸引他们点击并分享链接

康拓展开(hash算法中会用到)

康拓展开是一个全排列到一个自然数的双射(也就是某个全排列与某个自然数一一对应) 公式: X=a[n]*(n-1)!+a[n-1]*(n-2)!+...+a[i]*(i-1)!+...+a[1]*0! 其中,a[i]为整数,并且0<=a[i]<i,1<=i<=n。(a[i]在不同应用中的含义不同); 典型应用: 计算当前排列在所有由小到大全排列中的顺序,也就是说求当前排列是第

csu 1446 Problem J Modified LCS (扩展欧几里得算法的简单应用)

这是一道扩展欧几里得算法的简单应用题,这题是在湖南多校训练赛中队友ac的一道题,在比赛之后请教了队友,然后自己把它a掉 这也是自己独自做扩展欧几里得算法的题目 题意:把题意转变下就变成了:求d1*x - d2*y = f2 - f1的解,很明显用exgcd来解 下面介绍一下exgcd的一些知识点:求ax + by = c的解 一、首先求ax + by = gcd(a,b)的解 这个