算法-保证图可完全遍历-并查集

使用并查集解决遍历所有点求最短路径问题——路径压缩 并查集解决最短路径 阅读详情

1、题目介绍

Alice 和 Bob 共有一个无向图,其中包含 n 个节点和 3  种类型的边:

类型 1:只能由 Alice 遍历。
类型 2:只能由 Bob 遍历。
类型 3:Alice 和 Bob 都可以遍历。
给你一个数组 edges ,其中 edges[i] = [typei, ui, vi] 表示节点 ui 和 vi 之间存在类型为 typei 的双向边。请你在保证图仍能够被 Alice和 Bob 完全遍历的前提下,找出可以删除的最大边数。如果从任何节点开始,Alice 和 Bob 都可以到达所有其他节点,则认为图是可以完全遍历的。

返回可以删除的最大边数,如果 Alice 和 Bob 无法完全遍历图,则返回 -1 。
image-20210127170828361
输入:n = 4, edges = [[3,1,2],[3,2,3],[1,1,3],[1,2,4],[1,1,2],[2,3,4]]
输出:2
解释:如果删除 [1,1,2] 和 [1,1,3] 这两条边,Alice 和 Bob 仍然可以完全遍历这个图。再删除任何其他的边都无法保证图可以完全遍历。所以可以删除的最大边数是 2 。

2、题目分析

  • 考虑使用贪心和并查集解决本问题,将删除边的操作转换为添加边

  • 1、贪心:

    • 公共边/类型3可以让Alian和Bob都遍历,首先考虑添加公共边:如果两个节点已经在一个连通分量,那么添加公共边无意义,这条公共边被舍弃;如果不在,那么添加公共边并更新连通分量
    • Alian/Bob独占边:插入公共边之后开始插入独占边,如果对Alian/Bob某一方两个端点已连通的时候,就要舍弃这条边;否则就添加且更新连通分支
    • 最后输出/返回舍弃的边的数量
  • 2、并查集:先了解一下什么是并查集,并查集的作用是合并相关联的节点并检查两个节点是否先关联,特别适合对图的连通分支的操作。

    看到并查集的初始化代码之后,可以把并查集想象成是n个互不相干的根节点:如果要union合并两个节点,就把一个节点变成另外一个的子节点,这样两个节点就属于一个连通分支了;如果要检查两个节点是否连通,比较根节点是否一致即可;

    class UnionFind{
        //节点数组
        private int[] parent;
        //数组大小
        private int size;
        //记录剩余的连通分支数
        private int count;
        
        //带参的构造函数
        public UnionFind(int n){
            this.size = n;
            this.count = size;
            this.parent = new int[size];
            for(int i = 0;i < size;i++){
                parent[i] = i;
            }
        }
        
        //查找函数,找到根节点
        public int find(int x){
            //递归查找,比while循环要稍快
            if(x != parent[x]){
                parent[x] = find(parent[x]);
            }
            return parent[x];
        }
        
        //合并函数,将一个节点和另外一个连接
        public void union(int x,int y){
            //x的根值
            int x_root = find(x);
            //y的根值
            int y_root = find(y);
            //x和y有相同的根,证明在一棵树/连通分支上
            if(x_root = y_root)
                return;
            //不在一个连通分支上则连通两个节点
            parent[x_root] = y_root;
            //有合并操作的时候,连通分支少一个
            count--;
        }
        
        //判断函数,判断两个节点是否在一个连通分支上
        public boolean isConnected(int x,int y){
            return find(x) == find(y);
        }
        
        //返回连通分支数,count使用private修饰符保护
        public int getCount(){
            return count;
        }
    }
    
  • 操作记录,要设置一个变量记录最后剩余的连通分支数量,每次有合并的时候连通分支数目减一

3、代码分析

class Solution {
    public int maxNumEdgesToRemove(int n, int[][] edges) {
        //为每个人初始化一个并查集对象
        UnionFind un_Alian = new UnionFind(n);
        UnionFind un_Bob= new UnionFind(n);
        int res = 0;
        
        for(int[] edge : edges){
            //1、先找出所有公共边
            if(edge[0] == 3){
                //当前两个节点已经连通,删去一条边,加入公共边,因为两个都设置,所有判断一条边即可
                if(!un_Alian.union(edge[1],edge[2])/* || un_Bob.isConnected(edge[1],edge[2])*/){
                    res++;
                }
                //不连通的时候,此时union()已经将Alian相连,只需要连接Bob
                else{
                    un_Bob.union(edge[1],edge[2]);
                }
            }
        }
        //独占边情况
        for(int[] edge : edges){
            //2、Alice独占的边
            if(edge[0] == 1){
                if(!un_Alian.union(edge[1],edge[2])){
                    ++res;
                }  
            }
            //3、Bob独占的边
            else if(edge[0] == 2){
                if(!un_Bob.union(edge[1],edge[2])){
                    ++res;
                }
            }
        }
        //不连通的时候
        if(un_Alian.getCount() != 1 || un_Bob.getCount() != 1){
            return -1;
        }
        return res;
    }
}

//并查集模板
class UnionFind{
    private int[] parent;
    private int size;
    private int count;

    public UnionFind(int n){
        this.size = n;
        this.count = n;
        parent = new int[size + 1];
        //节点编号从1开始,也可以不动模板改动本题的函数
        for(int i = 1;i <= size;++i){
            parent[i] = i;
        }
    }

    public int find(int x){//超时的原因在这里
        if(x != parent[x]){
            parent[x] = find(parent[x]);
        }
        return parent[x];
    }
    public boolean isConnected(int x,int y){
        return find(x) == find(y);
    }
    //加一个判断功能,返回值是boolean型
    public boolean union(int x,int y){
         int x_root = find(x);
         int y_root = find(y);
         if(x_root == y_root) return false;
         parent[x_root] = y_root;
         count--;
         return true;
    }

    public int getCount(){
        return count;
    }
}

4、复杂度分析

  • 时间复杂度:O(m * a(n)),m是数组的长度,a()是阿克曼函数的反函数
  • 空间复杂度:O(n),new两个并查集需要2n的额外空间
MATLAB点云处理(八):为点云添加高斯噪声 本文对如何借助MATLAB,为点云添加高斯噪声做出了说明,并给出实现代码。 阅读详情

相关推荐

DBeaver连接ClickHouse保姆级教程:从安装到成功测试(附驱动下载问题解决)

本文提供了一份详细的DBeaver连接ClickHouse实战指南,重点解决了驱动下载失败等常见问题。文章从环境准备、DBeaver安装讲起,详细阐述了手动配置ClickHouse驱动的可靠方案,并逐步指导完成连接配置与测试,最后介绍了基础操作与查询优化技巧,旨在帮助用户高效完成连接并快速上手使用。

pink的博客 877

1579. 保证图可完全遍历(并查集)(傻瓜教程)(python)(LC)

1579. 保证图可完全遍历 Alice 和 Bob 共有一个无向图,其中包含 n 个节点和 3 种类型的边: 类型 1:只能由 Alice 遍历。 类型 2:只能由 Bob 遍历。 类型 3:Alice 和 Bob 都可以遍历。 给你一个数组 edges ,其中 edges[i] = [typei, ui, vi] 表示节点 ui 和 vi 之间存在类型为 typei 的双向边。请你在保证图仍能够被 Alice和 Bob 完全遍历的前提下,找出可以删除的最大边数。如果从任何节点开始,Alice 和 Bo

qq_51174011的博客 298

基于java的汉服商城管理系统设计与实现的详细项目实例

本文介绍了一个基于Java的汉服商城管理系统设计与实现项目。该项目采用三层架构设计,包含用户模块、商品管理、订单处理、支付结算等核心功能,支持多角色权限控制和响应式前端界面。 系统创新点包括: 专业化的汉服商品管理,支持多规格属性组合 高并发订单处理机制,确保库存实时同步 个性化智能推荐算法提升用户体验 细粒度权限控制保障系统安全 项目采用SpringBoot+MyBatis技术栈,前端使用React框架实现跨设备兼容。数据库设计包含用户表、商品表、订单表等10个核心表,通过事务管理确保数据一致性。 系统解

优质创作者: 人工智能技术领域 对于有一定基础的 MATLAB和Python带具体需求都可以详谈 MATLAB和Python可以提供代码调试服务加油 谢谢 你的鼓励是我前行的动力 谢谢支持 加油 谢谢 802

Leetcode(5)——遍历,并查集,回溯法和二分查找

格式: 题号+题名+简单思路+code 回溯思想 终止条件 选择列表 当前路径的记录 更新和撤销 T46: 全排列 注意切片指针/深拷贝 func permute(nums []int) [][]int { curr:=[]int{} ans:=[][]int{} assist(nums, &curr, &ans) return ans } func assist(nums []int, curr *[]int, ans *[][]int) {

某热心知名群众的博客 3928

WPF窗口定位技巧:从基础到高级的三种实现方法

本文详细解析WPF窗口定位的三种核心方法:屏幕居中(CenterScreen)、父窗口居中(CenterOwner)和手动定位(Manual)。通过对比其适用场景、实现代码与注意事项,帮助开发者根据实际需求选择最佳方案,从而提升WPF应用程序的用户体验与专业度。

weixin_29224309的博客 272

Python+ArcGIS实战:5步搞定土壤类型预测(附随机森林模型配置技巧)

本文详细介绍了如何结合Python与ArcGIS,利用随机森林模型进行土壤类型预测。通过5个核心步骤——数据预处理、样本创建、模型构建、空间预测与精度验证,构建了一套自动化、高精度的空间预测工作流,并提供了关键的模型配置与调参技巧,助力GIS开发者高效完成土壤制图任务。

weixin_29227585的博客 395

并查集中如何合并和遍历

void union(int a,int b){ int fa=findfather(a); int fb=findfather(b); if(fa!=fb)father[fa]=fb;//而不是a,b } 遍历的时候应该用hashtable[findfather(i)]而不是hashtable[father[i]]

qq_30339595的博客 706

EMC原理-传导(共模、差模)与辐射(近场、远场)详解

本文深入介绍了电磁兼容(EMC)的基本概念,包括EMI和EMS,以及如何处理传导干扰(共模、差模)和辐射干扰(近场、远场)。详细讨论了近场感应、远场辐射的原理,滤波器和屏蔽技术在抑制噪声信号中的作用。此外,探讨了差模和共模干扰的来源、影响及滤除方法,如使用差模电感、电容和共模线圈。最后,提到了穿心电容在滤除高频噪声中的应用。

让你爱上电路设计 3550

POJ2236(并查集,逐一遍历)

Wireless Network Time Limit: 10000MS Memory Limit: 65536K Total Submissions: 38055 Accepted: 15753 Description An earthquake takes place in Southeast Asia. The ACM (Asia Cooperated Medical team)...

weixin_40488730的博客 547

Agent Skills应用解析:构建可扩展、高效率AI探员

Agent Skills是一个简洁而强大的概念:它是一个包含组织化的指令、脚本和资源的文件夹,智能体可以动态地发现并加载这些内容,以在特定任务中表现更佳。可组合性(Composability):一个Agent Skill是一个独立的、封装良好的能力单元。开发者可以为不同的功能(例如PDF处理、网络浏览、数据分析)创建独立的技能,然后根据需要将它们组合起来,赋能不同的智能体。这意味着不再需要为每个用例构建碎片化、定制设计的智能体,而是可以通过组合现有技能来快速构建新的专业智能体。

形上得其象,形下合于数;阴阳自济,玄理自明。 1627

【GitHub项目实战】OpenAvatarChat 搭建实时交互数字人

OpenAvatarChat 项目构建了一个集成语音识别、大语言模型、语音合成、表情驱动和实时通信于一体的虚拟人系统,具备本地优先、模块解耦、快速部署的特点。系统通过配置文件统一管理组件,支持多种组合方案,适用于低资源设备和私有化部署场景。配置逻辑清晰、模块职责明确,能快速启动并实现端到端语音交互流程,为多模态系统学习与实践提供了结构完整的工程参考。

Mr数据杨 2749

【算法练习】leetcode每日一题/并查集 1579. 保证图可完全遍历

1579. 保证图可完全遍历 难度困难 Alice 和 Bob 共有一个无向图,其中包含 n 个节点和 3 种类型的边: 类型 1:只能由 Alice 遍历。 类型 2:只能由 Bob 遍历。 类型 3:Alice 和 Bob 都可以遍历。 给你一个数组edges,其中edges[i] = [typei, ui, vi]表示节点ui和vi之间存在类型为typei的双向边。请你在保证图仍能够被 Alice和 Bob 完全遍历的前提下,找出可以删除的最大边数。如果从任何节点开始,...

一蓑烟雨任平生 335

YOLOv8融合可变形注意力(DAT)实战教程:暴力涨点的科研级注意力机制优化方案

DAT的“可变形注意力”为目标检测的“精准特征捕捉”提供了全新思路,而YOLOv8的工程化优势让这种科研创新能快速落地到工业场景。希望这篇教程能帮你在“注意力机制优化+复杂场景检测”的痛点上找到突破口。如果你在实操中遇到“涨点不明显”的问题,不妨回到“DAT的采样点是否贴合目标形状”“注意力权重是否有效过滤背景”这些细节上找原因——科研的价值,就在于在细节打磨中推动技术进步。祝你在DAT与YOLOv8的结合探索中,既能做出有说服力的实验成果,又能沉淀出解决异形目标检测难题的实用经验。

know_F0727的博客 83

算法练习帖--57--保证图可完全遍历(Java)

保证图可完全遍历(并查集) 一、题目简介 Alice 和 Bob 共有一个无向图,其中包含 n 个节点和 3 种类型的边: 类型 1:只能由 Alice 遍历。 类型 2:只能由 Bob 遍历。 类型 3:Alice 和 Bob 都可以遍历。 给你一个数组 edges ,其中 edges[i] = [typei, ui, vi] 表示节点 ui 和 vi 之间存在类型为 typei 的双向边。请你在保证图仍能够被 Alice和 Bob 完全遍历的前提下,找出可以删除的最大边数。如果从任何节点开始,Alic

Inmaturity_7的博客 223

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

LeetCode 1579. 保证图可完全遍历(并查集)

文章目录1. 题目2. 解题 1. 题目 Alice 和 Bob 共有一个无向图,其中包含 n 个节点和 3 种类型的边: 类型 1:只能由 Alice 遍历。 类型 2:只能由 Bob 遍历。 类型 3:Alice 和 Bob 都可以遍历。 给你一个数组 edges ,其中 edges[i] = [typei, ui, vi] 表示节点 ui 和 vi 之间存在类型为 typei 的双向边。 请你在保证图仍能够被 Alice和 Bob 完全遍历的前提下,找出可以删除的最大边数。 如果从任何节点开始,A

Michael是个半路程序员 981

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

leetcode1579- 保证图可完全遍历(稍微绕点弯的并查集)

leetcode1579- 保证图可完全遍历(稍微绕点弯的并查集)介绍并查集模板题目解题思路分析题目意图分析解题方法解题步骤代码效果展示 介绍 我的LeetCode主页,一题一题解 标签:并查集 1579. 保证图可完全遍历 难度 困难 1579. 保证图可完全遍历 https://leetcode-cn.com/problems/remove-max-number-of-edges-to-keep-graph-fully-traversable/ 并查集模板 在正式开始做题之前,首先提供一个并查集类,

Alivorth的博客 193

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

【LeetCode】1579. 保证图可完全遍历 Remove Max Number of Edges to Keep Graph Fully Traversable

作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 目录题目描述题目大意解题思路并查集代码欢迎加入组织日期 题目地址:https://leetcode-cn.com/problems/remove-max-number-of-edges-to-keep-graph-fully-traversable 题目描述 Alice 和 Bob 共有一个无向图,其中包含 n 个节点和 3 种类型的边: 类型 1:只能由 Alice 遍历。.

负雪明烛 1098

Leetcode1579. 保证图可完全遍历

Leetcode1579. 保证图可完全遍历 题目链接 思路 首先使用并查集检查Alice和Bob是否分别能够遍历整张图,如果一人不行则返回-1。然后,开始找两个人都能遍历的情况下的最小边,我们可以只当,两人都遍历的情况下最多的边数为2*(n-1)其中n为顶点数。为了使边数减少,我们可以这样考虑如果存在公共边即类型3我们应将该边对应的两个结点合并,因为这样可以至少减少一条边(这是一种贪心思路),我们这样考虑,如果存在一条公共边他们两个人在遍历图的时候一个人选了另外一个人没选,那么我们可以让没选的那个人加上这

qq_47373183的博客 207

leetcode 1579.保证图可完全遍历

leetcode 1579.保证图可完全遍历 题干 Alice 和 Bob 共有一个无向图,其中包含 n 个节点和 3  种类型的边: 类型 1:只能由 Alice 遍历。 类型 2:只能由 Bob 遍历。 类型 3:Alice 和 Bob 都可以遍历。 给你一个数组 edges ,其中 edges[i] = [typei, ui, vi] 表示节点 ui 和 vi 之间存在类型为 typei 的双向边。请你在保证图仍能够被 Alice和 Bob 完全遍历的前提下,找出可以删除的最大边数

玛软的垃圾桶 155

1579. 保证图可完全遍历

Alice 和 Bob 共有一个无向图,其中包含 n 个节点和 3种类型的边: 类型 1:只能由 Alice 遍历。 类型 2:只能由 Bob 遍历。 类型 3:Alice 和 Bob 都可以遍历。 给你一个数组 edges ,其中 edges[i] = [typei, ui, vi]表示节点 ui 和 vi 之间存在类型为 typei 的双向边。请你在保证图仍能够被 Alice和 Bob 完全遍历的前提下,找出可以删除的最大边数。如果从任何节点开始,Alice 和 Bob 都可以到达所有其他节点,...

junruit的博客 261

leetcode 保证图可完全遍历 并查集+生成树 优先构造2颗生成树公共部分 好题

保证图可完全遍历 Alice 和 Bob 共有一个无向图,其中包含 n 个节点和 3 种类型的边: 类型 1:只能由 Alice 遍历。 类型 2:只能由 Bob 遍历。 类型 3:Alice 和 Bob 都可以遍历。 给你一个数组 edges ,其中 edges[i] = [typei, ui, vi] 表示节点 ui 和 vi 之间存在类型为 typei 的双向边。请你在保证图仍能够被 Alice和 Bob 完全遍历的前提下,找出可以删除的最大边数。如果从任何节点开始,Alice 和 Bob 都可以

马角的逆袭的博客 290

1579. 保证图可完全遍历(并查集)

package com.heu.wsq.leetcode.bingchaji; import java.util.ArrayList; import java.util.List; /** * 1579. 保证图可完全遍历 * @author wsq * @date 2021/1/27 * Alice 和 Bob 共有一个无向图,其中包含 n 个节点和 3 种类型的边: * 类型 1:只能由 Alice 遍历。 * 类型 2:只能由 Bob 遍历。 * 类型 3:Alice 和 Bob

Codeoh的博客 204

算法练习:保证图可完全遍历

题目: Alice 和 Bob 共有一个无向图,其中包含 n 个节点和 3 种类型的边: 类型 1:只能由 Alice 遍历。 类型 2:只能由 Bob 遍历。 类型 3:Alice 和 Bob 都可以遍历。 给你一个数组 edges ,其中 edges[i] = [typei, ui, vi] 表示节点 ui 和 vi 之间存在类型为 typei 的双向边。请你在保证图仍能够被 Alice和 Bob 完全遍历的前提下,找出可以删除的最大边数。如果从任何节点开始,Alice 和 Bob 都可以到达所有其他

qq_45711100的博客 316

LeetCode 1579. 保证图可完全遍历(困难)

1579. 保证图可完全遍历 Alice 和 Bob 共有一个无向图,其中包含 n 个节点和 3 种类型的边: 类型 1:只能由 Alice 遍历。 类型 2:只能由 Bob 遍历。 类型 3:Alice 和 Bob 都可以遍历。 给你一个数组edges,其中edges[i] = [typei, ui, vi]表示节点ui和vi之间存在类型为typei的双向边。请你在保证图仍能够被 Alice和 Bob 完全遍历的前提下,找出可以删除的最大边数。如果从任何节点开始,Alice ...

VictorKa的博客 195

leetcode 1579. 保证图可完全遍历(并查集)

Alice 和 Bob 共有一个无向图,其中包含 n 个节点和 3 种类型的边: 类型 1:只能由 Alice 遍历。 类型 2:只能由 Bob 遍历。 类型 3:Alice 和 Bob 都可以遍历。 给你一个数组 edges ,其中 edges[i] = [typei, ui, vi] 表示节点 ui 和 vi 之间存在类型为 typei 的双向边。请你在保证图仍能够被 Alice和 Bob 完全遍历的前提下,找出可以删除的最大边数。如果从任何节点开始,Alice 和 Bob 都可以到达所有其他节点,则

weixin_44560620的博客 177

LeetCode:1579. Remove Max Number of Edges to Keep Graph Fully Traversable保证图可完全遍历(C语言)

题目描述: Alice 和 Bob 共有一个无向图,其中包含 n 个节点和 3 种类型的边: 类型 1:只能由 Alice 遍历。 类型 2:只能由 Bob 遍历。 类型 3:Alice 和 Bob 都可以遍历。 给你一个数组 edges ,其中 edges[i] = [typei, ui, vi] 表示节点 ui 和 vi 之间存在类型为 typei 的双向边。请你在保证图仍能够被 Alice和 Bob 完全遍历的前提下,找出可以删除的最大边数。如果从任何节点开始,Alice 和 Bob 都可以到达所

C/C++攻城狮 256
上一篇: Netty-入门介绍-清晰明了
下一篇: Netty-三种IO方式-对比介绍
酱油瓶啤酒杯
博客等级 码龄8年 35粉丝 135原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值