【八十二】【算法分析与设计】2421. 好路径的数目,928. 尽量减少恶意软件的传播 II,并查集的应用,元素信息绑定下标一起排序,元素通过下标进行绑定

2421. 好路径的数目

给你一棵 n 个节点的树(连通无向无环的图),节点编号从 0n - 1 且恰好有 n - 1 条边。

给你一个长度为 n 下标从 0 开始的整数数组 vals ,分别表示每个节点的值。同时给你一个二维整数数组 edges ,其中 edges[i] = [a(i), b(i)] 表示节点 a(i)b(i)( )之间有一条 无向 边。

一条 好路径 需要满足以下条件:

  1. 开始节点和结束节点的值 相同

  2. 开始节点和结束节点中间的所有节点值都 小于等于 开始节点的值(也就是说开始节点的值应该是路径上所有节点的最大值)。

请你返回不同好路径的数目。

注意,一条路径和它反向的路径算作 同一 路径。比方说, 0 -> 11 -> 0 视为同一条路径。单个节点也视为一条合法路径。

示例 1:

输入:vals = [1,3,2,1,3], edges = [[0,1],[0,2],[2,3],[2,4]] 输出:6 解释:总共有 5 条单个节点的好路径。 还有 1 条好路径:1 -> 0 -> 2 -> 4 。 (反方向的路径 4 -> 2 -> 0 -> 1 视为跟 1 -> 0 -> 2 -> 4 一样的路径) 注意 0 -> 2 -> 3 不是一条好路径,因为 vals[2] > vals[0] 。

示例 2:

输入:vals = [1,1,2,2,3], edges = [[0,1],[1,2],[2,3],[2,4]] 输出:7 解释:总共有 5 条单个节点的好路径。 还有 2 条好路径:0 -> 1 和 2 -> 3 。

示例 3:

输入:vals = [1], edges = [] 输出:1 解释:这棵树只有一个节点,所以只有一条好路径。

提示:

  • n == vals.length

  • 1 <= n <= 3 * 10(4)

  • 0 <= vals[i] <= 10(5)

  • edges.length == n - 1

  • edges[i].length == 2

  • 0 <= a(i), b(i) < n

  • a(i) != b(i)

  • edges 表示一棵合法的树。

1.

对于所有的边元素,我们可以得到他max的vals的值,并且可以构造一个max数组一一对应.

max进行排序,从小到大排序,并且是绑定下标进行排序.

这样我们就可以按照元素的max信息顺序进行访问元素本身.

2.

对于每一个边,如果两个点的最大值是不一样的,那么肯定不是好路径.

如果两个点的最大值是一样的,那么好路径的个数是两个点所在集合元素个数相乘,然后这两个结合合并.

 
class Solution {
public:vector<int> vals;//每一个点的值vector<vector<int>> edges;//每一个边信息int ret;//存储结果using p = pair<int, int>;//定义pairvector<p> max_edge;//为了绑定max和下标一起排序int n;//点的个数struct node {//存储所有元素对于的其他的信息int max;//存储集合最大值信息int size;//存储集合最大值个数信息int father;//并查集核心部分};vector<node> vec;//所有元素对应的其他的信息vector<int> st;//用vector模拟栈int _find(int i) {//并查集中找i下标对应集合的代表元素的下标while (!(i == vec[i].father)) {//当前节点是i,出口时i=vec[i].fatherst.push_back(i);//用栈存储走过的路i = vec[i].father;//进入下一节点的操作}while (st.size()) {//将所有走过的路的father直接设置为集合代表元素的下标//扁平化处理vec[st.back()].father = i;st.pop_back();}return i;}bool isSameSet(int x, int y) { return _find(x) == _find(y); }//判断是否是同一个集合void _union(int x, int y) {//将两个集合进行合并if (_find(x) == _find(y))return;else {int rx = _find(x);int ry = _find(y);int maxx = vec[rx].max;int maxy = vec[ry].max;if (maxx == maxy)//如果最大值是一样的,那么最大值的个数相加vec[ry].size = vec[rx].size + vec[ry].size;else if (maxx > maxy)//如果最大值不是一样的,只需要考虑这一种情况,修改ry的sizevec[ry].size = vec[rx].size;vec[ry].max = max(vec[rx].max, vec[ry].max);vec[rx].father = vec[ry].father;}}void init() {//正式解题操作之前的初始化操作n = edges.size();for (int i = 0; i < n; i++) {max_edge.push_back({max(vals[edges[i][0]], vals[edges[i][1]]), i});//vector中绑定max值和下标,一起排序}sort(max_edge.begin(), max_edge.end(),[](const auto& a, const auto& b) { return a.first < b.first; });//sort的lambda写法//第三个参数直接以函数的信息写出来了//关注于第三个参数,直接使用auto,用于判断a是否位于b的前面//pair中first存储的是max信息vec.clear(), vec.resize(vals.size());for (int i = 0; i < vals.size(); i++) {//初始化vec信息vec[i].father = i;vec[i].max = vals[i];vec[i].size = 1;}}void solve() {//正式开始解题步骤for (int i = 0; i < max_edge.size(); i++) {int id = max_edge[i].second;//找到边的下标int id1, id2;id1 = edges[id][0];//找边的两个点id2 = edges[id][1];int max_id1 = vec[_find(id1)].max;int max_id2 = vec[_find(id2)].max;if (max_id1 == max_id2) {//如果最大值是一样的,维护retret += vec[_find(id1)].size * vec[_find(id2)].size;_union(id1, id2);} else {//如果不是一样的_union(id1, id2);}}ret += vals.size();//最后不要忘记了ret需要加入没一个独立的点}int numberOfGoodPaths(vector<int>& _vals, vector<vector<int>>& _edges) {vals = _vals;edges = _edges;init();solve();return ret;}
};

928. 尽量减少恶意软件的传播 II

给定一个由 n 个节点组成的网络,用 n x n 个邻接矩阵 graph 表示。在节点网络中,只有当 graph[i][j] = 1 时,节点 i 能够直接连接到另一个节点 j

一些节点 initial 最初被恶意软件感染。只要两个节点直接连接,且其中至少一个节点受到恶意软件的感染,那么两个节点都将被恶意软件感染。这种恶意软件的传播将继续,直到没有更多的节点可以被这种方式感染。

假设 M(initial) 是在恶意软件停止传播之后,整个网络中感染恶意软件的最终节点数。

我们可以从 initial删除一个节点并完全移除该节点以及从该节点到任何其他节点的任何连接。

请返回移除后能够使 M(initial) 最小化的节点。如果有多个节点满足条件,返回索引 最小的节点

示例 1:

输入:graph = [[1,1,0],[1,1,0],[0,0,1]], initial = [0,1] 输出:0

示例 2:

输入:graph = [[1,1,0],[1,1,1],[0,1,1]], initial = [0,1] 输出:1

示例 3:

输入:graph = [[1,1,0,0],[1,1,1,0],[0,1,1,1],[0,0,1,1]], initial = [0,1] 输出:1

提示:

  • n == graph.length

  • n == graph[i].length

  • 2 <= n <= 300

  • graph[i][j]01.

  • graph[i][j] == graph[j][i]

  • graph[i][i] == 1

  • 1 <= initial.length < n

  • 0 <= initial[i] <= n - 1

  • initial 中每个整数都不同

1.

解题的思路,首先有许多个点,有毒点有正常点.

把所有的正常点相互连接的部分合并成一个集合.

遍历所有的毒点,访问所有的与毒点相连的集合,给这个集合打上标签,这个标签是这个集合与之相连的毒点.

因此这个标签实际上可能有多个,也可有可能只有一个,或者没有.

最后搞一个count数组对应所有的毒点,遍历所有的集合,如果该集合的标签只有一个,那么对应的count加上该集合的所有元素.

遍历count找到最大的count值并且找到下标,通过下标找到对应毒点的下标.

2.

需要注意的一点是,如果count值相等,需要返回较小值的毒点下标.

因此我们提前将it数组进行排序.

 
class Solution {
public:vector<vector<int>> g;//图的临界矩阵的存储方式vector<int> it;//毒点的下标,位置int ret;//最终结果存储遍历int n;//邻接矩阵的端点个数,也就是有多少个点struct node {//给每一个点,元素绑定一些信息,通过下标绑定所有的元素和元素对应的信息int father;//每一个元素的father下标,并查集的核心set<int> point_yuan;//每一个元素的毒点信息,实际上只需要关心集合头元素的该信息即可int size;//集合的元素个数};map<int, int> point_yuan_index;//将元素和下标进行映射,这样我们就可以通过元素找到对应的下标进而找到对应的所有的信息vector<node> v;//v表示所有元素对应的信息vector<int> st;//用vector模拟栈的实现,用于对并查集进行扁平化处理set<int> setnum;//set容器进行去重操作,存储所有的集合代表元素,代表元素的下标vector<int> count;//对应所有毒点的count,表示每一个毒点如果删去可以拯救的点的个数int _find(int i) {//并查集中查找的方法while (!(i == v[i].father)) {//当前节点是i位置,出口时i==v[i].fatherst.push_back(i);//对于每一个访问的下标进行存储,用栈存储走过的路i = v[i].father;//进入下一节点的操作}while (!st.empty()) {//对于所有走过的路,修改其father直接改为i位置,此时i是集合的代表元素的下标v[st.back()].father = i;st.pop_back();}return i;}void _union(int x, int y) {//集合的合并操作int rx = _find(x), ry = _find(y);//首先计算x下标,y下标所在集合的代表元素下标if (rx == ry)//如果所在集合一样就不需要合并return;else {//如果所在集合不一样就需要合并v[ry].size += v[rx].size;//对于每一个集合需要维护的信息是father和size信息//首先维护size信息,合并之后集合代表元素的下标是ry//所以需要改变ry的size信息v[rx].father = ry;}}void init() {//初始化函数,解题之前的必要操作sort(it.begin(), it.end());//首先给it进行排序n = g.size();//计算点的个数v.clear(), v.resize(n);//对元素信息进行分配空间for (int i = 0; i < n; i++) {v[i].father = i;//初始化fatherv[i].size = 1;//初始化size}for (int i = 0; i < it.size(); i++) {point_yuan_index[it[i]] = i;//毒点与下标建立映射}count.clear(), count.resize(it.size());ret = it[0];//一开始ret存储it第一个毒点的位置}void solve() {//正式开始解题过程for (int i = 0; i < n; i++) {//首先合并所有正常点for (int j = i + 1; j < n; j++) {if (g[i][j] == 1 && !point_yuan_index.count(i) &&!point_yuan_index.count(j))_union(i, j);//如果i,j都是正常点,并且ij之间有边,那么就合并在一起}}for (int i = 0; i < it.size(); i++) {//给所有的集合打标签int id = it[i];//找到毒点对于的下标for (int j = 0; j < n; j++) {if (id == j)continue;if (g[id][j] == 1) {v[_find(j)].point_yuan.insert(id);//set容器进行去重操作}}}for (int i = 0; i < n; i++) {//用set容器存储所有的集合的代表元素下标if (!point_yuan_index.count(i))//不考虑毒点setnum.insert(_find(i));}for (auto& x : setnum) {//遍历所有的集合点if (v[x].point_yuan.size() > 1)continue;else if (v[x].point_yuan.size() == 1) {//如果毒点连接只有一个,那么对于毒点的count值加上该集合的元素个数int id = point_yuan_index[*v[x].point_yuan.begin()];count[id] += v[x].size;}}int maxnum = 0;for (int i = 0; i < count.size(); i++) {//最后遍历count数组,找到最大值对应的毒点位置if (count[i] > maxnum) {maxnum = count[i];ret = it[i];}}}int minMalwareSpread(vector<vector<int>>& _graph, vector<int>& _initial) {g = _graph, it = _initial;init();solve();return ret;}
};

结尾

最后,感谢您阅读我的文章,希望这些内容能够对您有所启发和帮助。如果您有任何问题或想要分享您的观点,请随时在评论区留言。

同时,不要忘记订阅我的博客以获取更多有趣的内容。在未来的文章中,我将继续探讨这个话题的不同方面,为您呈现更多深度和见解。

谢谢您的支持,期待与您在下一篇文章中再次相遇!

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

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

相关文章

Windows PC上从零开始部署ChatGML-6B-int4量化模型

引言 ChatGLM-6B是清华大学知识工程和数据挖掘小组&#xff08;Knowledge Engineering Group (KEG) & Data Mining at Tsinghua University&#xff09;发布的一个开源的对话机器人。6B表示这是ChatGLM模型的60亿参数的小规模版本&#xff0c;约60亿参数。 ChatGML-6B-in…

『ZJUBCA Collaboration』WTF Academy 赞助支持

非常荣幸宣布&#xff0c;浙江大学区块链协会收到WTF Academy的赞助与支持&#xff0c;未来将共同开展更多深度合作。 WTF Academy是开发者的Web3开源大学&#xff0c;旨在通过开源教育让100,000名开发者进入到Web3。截止目前&#xff0c;WTF开源教程在GitHub收获超15,000 ⭐&a…

Python 机器学习 基础 之 监督学习/分类问题/回归任务/泛化、过拟合和欠拟合 基础概念说明

Python 机器学习 基础 之 监督学习/分类问题/回归任务/泛化、过拟合和欠拟合 基础概念说明 目录 Python 机器学习 基础 之 监督学习/分类问题/回归任务/泛化、过拟合和欠拟合 基础概念说明 一、简单介绍 二、监督学习 三、分类问题 四、回归任务 五、泛化、过拟合和欠拟合…

基于“PLUS模型+”生态系统服务多情景模拟预测实践技术应用

工业革命以来&#xff0c;社会生产力迅速提高&#xff0c;人类活动频繁&#xff0c;此外人口与日俱增对土地的需求与改造更加强烈&#xff0c;人-地关系日益紧张。此外&#xff0c;土地资源的不合理开发利用更是造成了水土流失、植被退化、水资源短缺、区域气候变化、生物多样性…

软件合规管理系统:Ping32提供软件合规管理方案

在当今复杂的商业环境中&#xff0c;企业软件合规管理已成为企业稳健运营和持续发展的关键因素。面对日益增长的法规要求和不断变化的市场环境&#xff0c;一套全面、高效的企业软件合规管理解决方案显得尤为重要。 该解决方案的核心在于构建一个综合合规管理平台&#xff0c;…

测试台架设计与制作

技术改变生活&#xff0c;懒人推动科技。人们在执行整车测试时&#xff0c;诸多不便&#xff0c;那如何提高测试效率、改善人员测试环境&#xff0c;各个汽车生态的设计者就为之费神。以CarPlay为例&#xff0c;从2013年的送整车去美国测试&#xff0c;发展到如今所有测试均可在…

基于springboot实现党员教育和管理系统项目【项目源码+论文说明】

基于springboot实现党员教育和管理系统演示 摘要 互联网发展至今&#xff0c;无论是其理论还是技术都已经成熟&#xff0c;而且它广泛参与在社会中的方方面面。它让信息都可以通过网络传播&#xff0c;搭配信息管理工具可以很好地为人们提供服务。针对信息管理混乱&#xff0c…

Android 开机启动扫描SD卡apk流程源码分析

在开机的时候&#xff0c;装在SD卡的apk和装在系统盘的apk扫描过程不一样&#xff0c;系统盘apk在系统启动过程中扫描&#xff0c;而SD卡上的就不是&#xff0c;等系统启动好了才挂载、扫描&#xff0c;下面就说下SD扫描的流程&#xff1a; 在SystemServer启动MountService&am…

美港通正规炒股市场恒生科指半日跌近2% 大型科技股集体下行

查查配5月7日电 7日,港股主要股指回调。截至午盘,恒生指数跌0.85%,恒生科技指数跌1.98%。 美港通证券以其专业的服务和较低的管理费用在市场中受到不少关注。该平台提供了实盘交易、止盈止损、仓位控制等功能,旨在为投资者提供更为全面的投资体验。 来源:Wind 盘面上,零售、软…

Zabbix+Grafana-常见报错及异常处理方式记录

文章目录 Zabbix安装篇Zabbix Web页面连接数据库失败 Zabbix使用篇中文显示不全 Zabbix报警篇新建的用户&#xff0c;配置报警后&#xff0c;无法收到报警 Grafana安装篇Windows系统安装时&#xff0c;添加zabbix报错&#xff1a;An error occurred within the plugin Zabbix安…

Python深度学习基于Tensorflow(5)机器学习基础

文章目录 监督学习线性回归逻辑回归决策树支持向量机朴素贝叶斯 集成学习BaggingBoosting 无监督学习主成分分析KMeans聚类 缺失值和分类数据处理处理缺失数据分类数据转化为OneHot编码 葡萄酒数据集示例 机器学习的流程如下所示&#xff1a; 具体又可以分为以下五个步骤&#…

精通Python(基础篇)pip命令大全(非常详细)零基础入门到精通,收藏这一篇就够了

一、pip介绍 1、pip是什么&#xff1f; 嘿&#xff01;你知道吗&#xff1f;pip 就像是 Python 的“快递小哥”&#xff0c;它负责帮你安装和管理那些不属于 Python 标准库的软件包。它就像是一个方便的工具&#xff0c;让你可以轻松地获取你需要的软件包&#xff0c;就像是在…

活动预告 | MVP 聚技站 - 低代码 AI 时代(一):初识 Power BI

点击蓝字 关注我们 编辑&#xff1a;Alan Wang 排版&#xff1a;Rani Sun MVP 聚技站 系列 微软最有价值专家推出“MVP 聚技站”系列主题专栏&#xff0c;邀请多位微软最有价值专家&#xff0c;针对初学者、开发者感兴趣的技术话题&#xff0c;带来专业的技术课程讲解与实践经验…

SpringBoot中这样用ObjectMapper

每次new一个单例化个性化配置小结 你要说他有问题吧&#xff0c;确实能正常执行&#xff1b;可你要说没问题吧&#xff0c;在追求性能的同学眼里&#xff0c;这属实算是十恶不赦的代码了。 首先&#xff0c;让我们用JMH对这段代码做一个基准测试&#xff0c;让大家对其性能有个…

Leetcode—2079. 给植物浇水【中等】

2024每日刷题&#xff08;130&#xff09; Leetcode—2079. 给植物浇水 实现代码 class Solution { public:int wateringPlants(vector<int>& plants, int capacity) {int ans 0;int step 0;int cap capacity;bool flag false;for(int i 0; i < plants.siz…

用C#打造精美系统托盘消息提醒,让你的应用更具魅力

使用效果&#xff1a; 代码&#xff1a; #region 消息框变量private Timer fadeTimer; // 定义计时器private int fadeSpeed 2;//淡出速度private NotifyIcon notifyIcon;//气泡通知private int opacityLevel 10;//不透明度public enum NotificationType{Error,//错误Warning…

WIFI模块UDP电脑端调试

一&#xff0c;两端都是电脑端 1&#xff0c;电脑本机的IP地址 192.168.137.1 2&#xff0c;新建两个不同的连接&#xff0c;注意端口 二&#xff0c;WIFI 模块和电脑端连接 1&#xff0c;设置模块端目标IP和端口&#xff0c;电脑端只接收数据的话&#xff0c;IP、端口可随…

【多客开源】游戏陪玩系统,游戏陪玩源码,游戏陪玩语音社交源码运营版游戏陪玩平台源码/tt语音聊天/声优服务/陪玩系统源码开黑/约玩源码

介绍 我们针对陪玩app源码市场的发展趋势&#xff0c;整合市面上主流陪玩app应用功能&#xff0c;自主开发了多客陪玩系统源码&#xff0c;并可为客户提供全部原生陪玩源码&#xff0c;进行二次开发&#xff0c;打造适用于线上游戏陪玩、语音聊天、心理咨询、情感陪伴等业务场…

Vue 中 $nextTick 的作用是什么?

目录 一、NextTick是什么 为什么要有nexttick 二、使用场景 三、实现原理 一、NextTick是什么 官方对其的定义 在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法&#xff0c;获取更新后的 DOM 什么意思呢&#xff1f; 我们可以理解成&#xff0c…

电动车违规停放监测摄像机

随着电动车的普及和城市交通拥堵问题的加剧&#xff0c;电动车的停放管理也成为一个亟待解决的难题。为了维护城市交通秩序和提高停车效率&#xff0c;一种名为电动车违规停放监测摄像机应运而生&#xff0c;成为城市管理的利器。这种电动车违规停放监测摄像机&#xff0c;利用…