题目: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 都可以到达所有其他节点,则认为图是可以完全遍历的。

返回可以删除的最大边数,如果 Alice 和 Bob 无法完全遍历图,则返回 -1 。

示例 1:

输入: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:

输入:n = 4, edges = [[3,1,2],[3,2,3],[1,1,4],[2,1,4]]
输出:0
解释:注意,删除任何一条边都会使 Alice 和 Bob 无法完全遍历这个图。

示例 3:

输入:n = 4, edges = [[3,2,3],[1,1,2],[2,3,4]]
输出:-1
解释:在当前图中,Alice 无法从其他节点到达节点 4 。类似地,Bob 也不能达到节点 1 。因此,图无法完全遍历。

提示:

  • 1 <= n <= 10^5
  • 1 <= edges.length <= min(10^5, 3 * n * (n-1) / 2)
  • edges[i].length == 3
  • 1 <= edges[i][0] <= 3
  • 1 <= edges[i][1] < edges[i][2] <= n
  • 所有元组 (typei, ui, vi) 互不相同

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/remove-max-number-of-edges-to-keep-graph-fully-traversable
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

题解

题目要求无向图可完全遍历即为无向图为连通图。因此,图的连通性可以利用并查集来解决。

求解并查集中可以删除的最大边数,实际上等价于求解可以利用的最小边数使得无向图的节点构成的并查集是连通的。

由于图中存在三种类型的边,type=3的边“最为强大”,Alice 和 Bob都可以连通,所以先将type=3的边输入到并查集中进行合并。

那么,合并成功则说明该条边是有效的边,可以连通这两个节点;合并失败则说明该条边是冗余边,可以删除(对应代码中ans++)。

type=1和type=2的边,处理上也类似。但是,这两类边进行合并时,使用的并查集是来自于上面得到的同一个并查集结果,因此,需要对并查集进行拷贝。

三类边遍历完后,如果两个并查集都是连通的,则表明可以遍历(返回ans),否则无法遍历(返回-1)。

代码

class UnionFind {private:int n;vector<int> parent;
public:UnionFind(int n_): n(n_) {parent.resize(n);for(int i = 0; i < n; i++) {parent[i] = i;}}UnionFind(UnionFind & uf) {n = uf.n;parent.resize(uf.parent.size());for(int i = 0; i < parent.size(); i++) {parent[i] = uf.parent[i];}}int find(int x) {int root = x;while(root != parent[root]) {root = parent[root];}while(x != parent[x]) {int tmp = parent[x];parent[x] = root;x = tmp;}return root;}bool merge(int x, int y) {int px = find(x);int py = find(y);if(px == py) {return false;}parent[py] = px;n--;return true;}int getSetNum(void) {return n;}
};class Solution {public:int maxNumEdgesToRemove(int n, vector<vector<int>>& edges) {UnionFind unionFind(n);int ans = 0;for(int i = 0; i < edges.size(); i++) {int type = edges[i][0];if (type != 3) {continue;}int u = edges[i][1] - 1;int v = edges[i][2] - 1;if(unionFind.merge(u, v) == false) {ans ++;}}UnionFind unionFind_alice(unionFind); for(int i = 0; i < edges.size(); i++) {int type = edges[i][0];int u = edges[i][1] - 1;int v = edges[i][2] - 1;if (type == 1) {if(unionFind_alice.merge(u, v) == false) {ans ++;}} else if(type == 2) {if(unionFind.merge(u, v) == false) {ans ++;}}}if(unionFind_alice.getSetNum() == 1 and unionFind.getSetNum() == 1) {return ans;}return -1;}
};

力扣题解-1579. 保证图可完全遍历(并查集)相关推荐

  1. 1579. 保证图可完全遍历

    链接:1579. 保证图可完全遍历 题解: https://www.bilibili.com/video/BV1PZ4y1N78t 1.贪心算法:先通过3类型的边,构成a和b的并查集.因为类型3的边, ...

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

    Alice 和 Bob 共有一个无向图,其中包含 n 个节点和 3 种类型的边: 类型 1:只能由 Alice 遍历. 类型 2:只能由 Bob 遍历. 类型 3:Alice 和 Bob 都可以遍历. ...

  3. 并查集之LeetCode1579. 保证图可完全遍历

    并查集之LeetCode1579. 保证图可完全遍历 前言 一,1579. 保证图可完全遍历 二,解题思路 三, 代码 总结 前言 算法之并查集 一,1579. 保证图可完全遍历 Alice 和 Bo ...

  4. 力扣有没有java_力扣题解

    这里将告诉您力扣题解,具体实现方法:题目描述 你是一个专业的小偷,计划偷窃沿街的房屋.每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚 ...

  5. leetcode_1579. 保证图可完全遍历

    一.题目内容 Alice 和 Bob 共有一个无向图,其中包含 n 个节点和 3  种类型的边: 类型 1:只能由 Alice 遍历. 类型 2:只能由 Bob 遍历. 类型 3:Alice 和 Bo ...

  6. 【手把手带你刷Leetcode力扣】10.数据结构 -图

    图: 顶点 邻居节点 边 度:边的数量 无向图 有向图 入度:指向该顶点的边的数量 出度:以该顶点为起点指向别的顶点的边的数量 权重图 最短路径 贝尔曼-福特算法(Bellman-Ford) 迪克斯特 ...

  7. 力扣题解-977. 有序数组的平方

    题目:977. 有序数组的平方 给定一个按非递减顺序排序的整数数组 A,返回每个数字的平方组成的新数组,要求也按非递减顺序排序. 示例 1: 输入:[-4,-1,0,3,10] 输出:[0,1,9,1 ...

  8. 力扣题解-1046. 最后一块石头的重量

    题目:1046. 最后一块石头的重量 有一堆石头,每块石头的重量都是正整数. 每一回合,从中选出两块 最重的 石头,然后将它们一起粉碎.假设石头的重量分别为 x 和 y,且 x <= y.那么粉 ...

  9. 力扣题解: 55. 跳跃游戏

    题目 给定一个非负整数数组 nums ,你最初位于数组的 第一个下标 . 数组中的每个元素代表你在该位置可以跳跃的最大长度. 判断你是否能够到达最后一个下标. 示例 1: 输入:nums = [2,3 ...

最新文章

  1. 朴素贝叶斯分类器简介及C++实现(性别分类)
  2. notification antd 弹窗使用示例
  3. excel工具栏隐藏了怎么办_真正的EXCEL隐藏技巧来啦!这5个你都会吗?
  4. VMware演示手机虚拟化
  5. Python学习笔记 -- 第一章
  6. 【git下载安装与配置】
  7. Word2016Word2019如何取消自动编号
  8. Spring IoC容器初始化过程分析
  9. Hibernate教程01
  10. DIY装机的看过来了! 一份实用的台式机硬件选取流程
  11. Java-常用实现分页查询
  12. java 数字大小写转换_阿拉伯数字大小写转换java工具
  13. 【dva】dva使用与实现(一)
  14. JS中onpropertychange事件和onchange事件区别
  15. c free()函数了解
  16. linux 打开终端自动运行脚本.barshrc
  17. 不懂就问,机器人做核酸是一种什么体验?|一周AI新闻
  18. 橘子学ES09之分词以及各大分词器
  19. Hadoop集群扩容新增4T硬盘(解决分区大小问题限制2T问题)
  20. 21/4/25 项目二:客户信息管理软件

热门文章

  1. 英特尔第十代处理器为什么不支持win7_10代处理器能装win7吗(9代cpu完美支持win7)...
  2. plsql批量导出、导入
  3. DSPack初次使用小结
  4. jQuery的基本使用方法
  5. 谷歌浏览器打开开发者模式还是无法添加油猴插件
  6. Android网络代理终极方案(适用于手机及电视盒子设备)
  7. 友善之臂6818内核编译
  8. 移动产品设计的八大设计原则
  9. 小学五年级趣味计算机课程,新媒体联盟 | 五年级小学段课程记——项目研究乐游学 趣味活动展风采...
  10. 西瓜书第一章阅读笔记