【个人笔记】685. 冗余连接 II 的解释(并查集)

news2024/9/21 2:32:45

一棵树有n个点和n条边,返回一条能删除的边,使得剩下的图是有 n 个节点的有根树。
解释:
注意不冗余的有根树的特性!**根节点入度为0,其余结点只有一个入度!**所以冗余的两种情况如下:
(1)有一个结点有2个入度(破环其他结点只有一个入度的条件)(可能成环可能不成环)
(2)形成一个每个节点都只有一个入度的环(破环根节点入度为0的条件)(成环)

对于情况(1),找到入度为2的结点(只关注入度)然后返回冗余的边就行了,但是:
1)当不成环时,返回任意一条都行
在这里插入图片描述
2)当成环时,要返回构成环的那条
在这里插入图片描述
所以这里只处理不成环的情况,入度为2时的边记为conflict,并跳过这种可能会导致冗余的边(无论是情况1)的真冗余边还是2)的非冗余边)。把成环的情况合并成到(2)解决。
(所以这里的情况2)出现时,可能造成冗余的边将被跳过)
(a)没去掉真正的冗余边,会出现情况(2)成环
在这里插入图片描述
或者(b)去掉了真正的冗余边,不会出现情况(2)
在这里插入图片描述
对(2),入度不为2的结点需要判定是否成环。如果该结点入度不为2,且属于同一个并查集,说明成环
记录形成有向环的那条边为circle,最后删掉构成环的边就可以了。


由于肯定存在一条冗余边,如果只有circle,那就是circle,如果只有conflict,那就是conflict,如果两个都有,说明是(1)的成环的情况(a)
但是!可能得到circle时是这样!构成环 的临门一脚不一定就是要删的那个,左边那个才是真正要删的!
在这里插入图片描述
所以需要用一个祖先数组ancestors记录“上一个结点”,要找到这个冗余边,就是找 指向edges[conflict][1]的上一个结点
因为只有入度不为2才会更新ancestors,所以ancestors记录的边必然排除了conflict记录的那条。有了ancestors,也不用存入度了,直接:如果ancestors[v]!=v,说明有其他父节点(入度为2)
即:冗余边为
(ancestors[edges[conflict][1]], edges[conflict][1])

class UnionFind{
    int[] parents;

    UnionFind(int l){
        parents = new int[l];
        Arrays.fill(parents, -1);
    }

    int find(int x){
        if (parents[x] < 0) {
            return x; // 如果是根节点,则返回
        }
        // 路径压缩
        return parents[x] = find(parents[x]);
    }

    void union(int x, int y) {
        int rootX = find(x);
        int rootY = find(y);
        if (rootX != rootY) {
            if (parents[rootX] < parents[rootY]) {  // 负数 <说明rootY下标的结点数更少
                parents[rootX] += parents[rootY];
                parents[rootY] = rootX;  // 小树合并到大树
            }else{
                parents[rootY] += parents[rootX];
                parents[rootX] = rootY;  // 小树合并到大树
            }  // 否则parent[rootX] = parent[rootY],不管
        }
    }
}

class Solution {
    public int[] findRedundantDirectedConnection(int[][] edges) {
        int conflict = -1;  // 冲突(俩父节点)
        int cycle = -1;     // 环

        int[] parent = new int[edges.length];
        for(int i=0; i<edges.length; i++){
            parent[i] = i;   // 要记录指向环路那个!!
        }

        UnionFind uf = new UnionFind(edges.length);
        for(int i=0; i<edges.length; i++){
            int u = edges[i][0]-1, v = edges[i][1]-1;
            if(parent[v]!=v){  // 入度为2
                conflict = i;   // 冲突,v有俩父结点不同的路径
            }else{  // 判断是否成环
                if(uf.find(u)==uf.find(v)){  // 成环
                    cycle = i;
                }else{  // 正常
                	parent[v] = u;  // u是v的父节点
                    uf.union(u, v);
                }
            }
        }
        if(conflict==-1){   // 只存在环路
            return edges[cycle];
        }
        if(cycle==-1){  // 只存在冲突
            return edges[conflict];
        }
        // 都有,则附加的边不可能是 [u,v]
        //(因为[u,v] 已经被记为导致冲突的边,不可能被记为导致环路出现的边),
        // 因此附加的边是 [parent[v],v]。
        int[] res = {parent[edges[conflict][1]-1]+1, edges[conflict][1]};
        return res;
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1928913.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

jmeter持续学习之---控制器

IF控制器 下面这种写法jmeter不推荐有性能的问题 jmeter推荐勾选上的这种写法 使用"Interpret Condition as Variable Expression"工具的性能要好一些 循环控制器 ForEach控制器 与用户定义的变量或者正则表达式提取器配合使用,循环读取。用户定义的变量或者正则…

彻底改变时尚:使用 GAN 实现 AI 的未来

彻底改变时尚&#xff1a;使用 GAN 实现 AI 的未来 一、介绍 想象一下&#xff0c;在这个世界里&#xff0c;时装设计师永远不会用完新想法&#xff0c;我们穿的每一件衣服都是一件艺术品。听起来很有趣&#xff0c;对吧&#xff1f;好吧&#xff0c;我们可以在通用对抗网络 &a…

路网双线合并单线——ArcGISpro 解决方法

路网双线合并成单线是一个在地图制作、交通规划以及GIS分析中常见的需求。双线路网定义&#xff1a;具有不同流向、不同平面结构的道路。此外&#xff0c;车道数较多的道路&#xff08;例如&#xff0c;双黄实线车道数大于4的道路&#xff09;也可以视为双线路网&#xff0c;本…

C++相关概念和易错语法(22)(final、纯虚函数、继承多态难点)

1.final final在继承和多态中都可以使用&#xff0c;在继承中是指不想将自己被继承&#xff0c;在多态中是指不想该函数被重写&#xff0c;比较简单&#xff0c;下面是一些使用例子。 2.纯虚函数 当我们需要抽象一个类的时候&#xff0c;我们就需要用到纯虚函数。所谓抽象的类…

深入理解I/O模型

目录 一、I/O 模型简介 二、I/O 模型 2.1 同步阻塞 I/O 2.2 同步非阻塞I/O 2.3 I/O多路复用 2.4 异步I/O 2.5 信号驱动 I/O 三、总结 一、I/O 模型简介 所谓的 I/O 就是计算机内存与外部设备之间拷贝数据数据的过程。有 5 中 I/O 模型&#xff0c;分别是同步阻塞 I/O、同步…

单端、差分信号处理抗干扰能力解析

采用仪表运放对信号源进行处理&#xff0c; 信号源地上有共模干扰&#xff0c;经过差分信号处理后Vout上不会有干扰&#xff0c;差分信号可以非常好的抗共模干扰。 经过差分信号处理后&#xff0c;以单端信号输出进入ADC还是会有干扰&#xff0c;所以信号链采用差分 处理后&…

Java二十三种设计模式-适配器模式(6/23)

适配器模式&#xff1a;使不兼容的接口协同工作的桥梁 引言 适配器模式&#xff08;Adapter Pattern&#xff09;是一种结构型设计模式&#xff0c;它允许不兼容的接口之间可以一起工作&#xff0c;通过将一个类的接口转换成客户端期望的另一个接口。 在计算机编程中&#x…

AI论文精读笔记-MAE

1. 论文基本信息 论文标题&#xff1a;Masked Autoencoders Are Scalable Vision Learners 作者&#xff1a;Kaiming He∗,† Xinlei Chen∗ Saining Xie Yanghao Li Piotr Doll ́ ar Ross Girshick 发表时间和期刊&#xff1a;19 Dec 2021; arxiv 论文链接&#xff1a;Mas…

苹果预计因Apple Intelligence引发设备升级潮

&#x1f989; AI新闻 &#x1f680; 苹果预计因Apple Intelligence引发设备升级潮 摘要&#xff1a;据彭博社报道&#xff0c;摩根士丹利将苹果列为首选股票&#xff0c;预期Apple Intelligence发布将引发创纪录的设备升级。分析师Erik Woodring 将苹果目标股价上调至273美元…

前端开发(基础)

目录 一、Web前端项目初始化 环境准备 创建项目 前端工程化配置 引入组件库 开发规范 全局通用布局 基础布局结构 全局底部栏 动态替换内容 全局顶部栏 通用路由菜单 支持多套布局 请求 请求工具库 全局自定义请求 自动生成请求代码 全局状态管理 全局权限管…

电力调度台如何助力电力指挥中心更智慧

在现代电力系统的复杂运行环境中&#xff0c;电力调度台正逐渐成为电力指挥中心实现智慧化管理的关键力量。 电力调度台具备强大的信息集成与处理能力。它能够将来自不同监测系统、传感器和数据源的海量数据汇聚一处&#xff0c;包括电力设备的实时运行状态、电力负荷的动态变化…

应急靶场(4):Windows Server 2019 - Web3

目录 一、攻击者的两个IP地址 二、隐藏用户名称 三、黑客遗留下的flag【3个】 下载好靶场&#xff08;前来挑战&#xff01;应急响应靶机训练-Web3&#xff09;并搭建好环境&#xff0c;使用帐号密码&#xff08;administrator / xj123456&#xff09;登录靶机。 一、攻击者的两…

张幼玲:心中有火,眼里有光照医路

在我们的传统社会中&#xff0c;男科医生这一职业往往被人们带着异样的眼光看待。然而&#xff0c;张幼玲却选择了这一领域&#xff0c;成为了一名专业男科医生。他以其丰富的临床经验、高超的医术和对患者的关爱&#xff0c;赢得了患者和社会的广泛赞誉。 张幼玲出生于一个中医…

ASP.NET Core----基础学习06----将所有数据在页面中显示 布局页面的使用

文章目录 1. 将数据以list的形式展示在页面中2. 布局页面的使用3. 自定义设置视图文件是否需要加载的JS 1. 将数据以list的形式展示在页面中 step1:在接口文件中添加新的方法GetAllStudents&#xff08;&#xff09; step2:在mock的数据中添加方法GetAllStudents&#xff08;&a…

7/13 - 7/15

vo.setId(rs.getLong("id"))什么意思&#xff1f; vo.setId(rs.getLong("id")); 这行代码是在Java中使用ResultSet对象&#xff08;通常用于从数据库中检索数据&#xff09;获取一个名为"id"的列&#xff0c;并将其作为long类型设置为一个对象…

Billu_b0x靶机

信息收集 使用arp-scan 生成网络接口地址来查看ip 输入命令&#xff1a; arp-scan -l 可以查看到我们的目标ip为192.168.187.153 nmap扫描端口开放 输入命令&#xff1a; nmap -min-rate 10000 -p- 192.168.187.153 可以看到开放2个端口 nmap扫描端口信息 输入命令&…

工作中项目git如何管理,冲突,push不上去如何解决

主要涉及的知识点 现在公司中一般的git仓库的管理方式是怎么样的代码为什么push不上线上仓库如何解决代码冲突 分支管理方式 git checkout -b 分支名字 是创建并切换到分支 git push origin 分支名字 推到远程仓库分支上 主流的git管理方式 共用一个仓库&#xff0c;不同…

Golang | Leetcode Golang题解之第237题删除链表中的节点

题目&#xff1a; 题解&#xff1a; func deleteNode(node *ListNode) {node.Val node.Next.Valnode.Next node.Next.Next }

解决宝塔Spring Boot项目获取不到环境变量的问题

问题描述 在使用宝塔面板管理Spring Boot项目时&#xff0c;可能会遇到代码无法获取 /etc/profile 文件中设置的Linux环境变量的问题。虽然在SSH终端中可以正常获取&#xff0c;但在通过宝塔面板启动的Spring Boot项目中&#xff0c;环境变量却无法被读取。 解决方案&#xf…

TS 入门(三):Typescript函数与对象类型

目录 前言回顾1. 函数类型a. 基本函数类型b. 可选参数和默认参数c. 剩余参数 2. 对象类型a. 基本对象类型b. 可选属性和只读属性 3. 类型别名和接口a. 类型别名b. 接口扩展 4. 类型推断和上下文类型a. 类型推断b. 上下文类型 扩展知识点&#xff1a;函数重载结语 前言 在前两章…