算法每日一题: 边权重均等查询 | 公共子祖先

大家好,我是星恒,今天给大家带来的是一道图里面有关公共子祖先的题目,理解起来简单,大家

题目:leetcode 2846
现有一棵由 n 个节点组成的无向树,节点按从 0 到 n - 1 编号。给你一个整数 n 和一个长度为 n - 1 的二维整数数组 edges ,其中 edges[i] = [ui, vi, wi] 表示树中存在一条位于节点 ui 和节点 vi 之间、权重为 wi 的边。另给你一个长度为 m 的二维整数数组 queries ,其中 queries[i] = [ai, bi] 。对于每条查询,请你找出使从 ai 到 bi 路径上每条边的权重相等所需的 最小操作次数 。在一次操作中,你可以选择树上的任意一条边,并将其权重更改为任意值。
注意:

  • 查询之间 相互独立 的,这意味着每条新的查询时,树都会回到 初始状态
  • 从 ai 到 bi的路径是一个由 不同 节点组成的序列,从节点 ai 开始,到节点 bi 结束,且序列中相邻的两个节点在树中共享一条边。

返回一个长度为 m 的数组 answer ,其中 answer[i] 是第 i 条查询的答案。

示例 1:
image.png

输入:n = 7, edges = [[0,1,1],[1,2,1],[2,3,1],[3,4,2],[4,5,2],[5,6,2]], queries = [[0,3],[3,6],[2,6],[0,6]]
输出:[0,0,1,3]
解释:第 1 条查询,从节点 0 到节点 3 的路径中的所有边的权重都是 1 。因此,答案为 0 。
第 2 条查询,从节点 3 到节点 6 的路径中的所有边的权重都是 2 。因此,答案为 0 。
第 3 条查询,将边 [2,3] 的权重变更为 2 。在这次操作之后,从节点 2 到节点 6 的路径中的所有边的权重都是 2 。因此,答案为 1 。
第 4 条查询,将边 [0,1]、[1,2]、[2,3] 的权重变更为 2 。在这次操作之后,从节点 0 到节点 6 的路径中的所有边的权重都是 2 。因此,答案为 3 。
对于每条查询 queries[i] ,可以证明 answer[i] 是使从 ai 到 bi 的路径中的所有边的权重相等的最小操作次数。

示例 2:
image.png

输入:n = 8, edges = [[1,2,6],[1,3,4],[2,4,6],[2,5,3],[3,6,6],[3,0,8],[7,0,2]], queries = [[4,6],[0,4],[6,5],[7,4]]
输出:[1,2,2,3]
解释:第 1 条查询,将边 [1,3] 的权重变更为 6 。在这次操作之后,从节点 4 到节点 6 的路径中的所有边的权重都是 6 。因此,答案为 1 。
第 2 条查询,将边 [0,3]、[3,1] 的权重变更为 6 。在这次操作之后,从节点 0 到节点 4 的路径中的所有边的权重都是 6 。因此,答案为 2 。
第 3 条查询,将边 [1,3]、[5,2] 的权重变更为 6 。在这次操作之后,从节点 6 到节点 5 的路径中的所有边的权重都是 6 。因此,答案为 2 。
第 4 条查询,将边 [0,7]、[0,3]、[1,3] 的权重变更为 6 。在这次操作之后,从节点 7 到节点 4 的路径中的所有边的权重都是 6 。因此,答案为 3 。
对于每条查询 queries[i] ,可以证明 answer[i] 是使从 ai 到 bi 的路径中的所有边的权重相等的最小操作次数。

提示:

  • 1 <= n <= 104
  • edges.length == n - 1
  • edges[i].length == 3
  • 0 <= ui, vi < n
  • 1 <= wi <= 26
  • 生成的输入满足 edges 表示一棵有效的树
  • 1 <= queries.length == m <= 2 * 104
  • queries[i].length == 2
  • 0 <= ai, bi < n

分析:
我们先看这道题的最直接的问题,如何寻找修改最少次数?我们只需要贪心的让两个点之间所有边,变为边权重出现最多的次数的权重,例如寻找a和b两点间修改的最小次数,如果ab两点间所有边中,权重2出现的次数最多,我们就让所有边的值改为2,这样修改的次数就最少了

好,知道这一点,我们的问题就变成了寻找两点间所有权重中,哪个权重出现次数最多。我们从提示中可以看出,权重的取值范围为1 - 26,我们可以计算每个点到根节点(开始节点)的每个权重出现的次数,然后当我们计算两点之间的最小 权重出现次数 时,这样计算:
我们还是使用之前的例子,计算a - b间:
count[a][i] + count[b][i] - 2count[c][i]

  • c是公共子祖先
  • count[a][i] 为节点a到根节点,权重为i的边出现的次数

难点:寻找公共祖先,这个大家可以在网上了解一下,这里使用Tarjan 算法
推荐链接:https://oi.wiki/graph/lca/#tarjan-%E7%AE%97%E6%B3%95

代码:

class Solution {static final int W = 26;public int[] minOperationsQueries(int n, int[][] edges, int[][] queries) {int m = queries.length;Map<Integer, Integer>[] neighbors = new Map[n];for (int i = 0; i < n; i++) {neighbors[i] = new HashMap<Integer, Integer>();}for (int[] edge : edges) {neighbors[edge[0]].put(edge[1], edge[2]);neighbors[edge[1]].put(edge[0], edge[2]);}List<int[]>[] queryArr = new List[n];for (int i = 0; i < n; i++) {queryArr[i] = new ArrayList<int[]>();}for (int i = 0; i < m; i++) {queryArr[queries[i][0]].add(new int[]{queries[i][1], i});queryArr[queries[i][1]].add(new int[]{queries[i][0], i});}int[][] count = new int[n][W + 1];boolean[] visited = new boolean[n];int[] uf = new int[n];int[] lca = new int[m];tarjan(0, -1, neighbors, queryArr, count, visited, uf, lca);int[] res = new int[m];for (int i = 0; i < m; i++) {int totalCount = 0, maxCount = 0;for (int j = 1; j <= W; j++) {int t = count[queries[i][0]][j] + count[queries[i][1]][j] - 2 * count[lca[i]][j];maxCount = Math.max(maxCount, t);totalCount += t;}res[i] = totalCount - maxCount;}return res;}public void tarjan(int node, int parent, Map<Integer, Integer>[] neighbors, List<int[]>[] queryArr, int[][] count, boolean[] visited, int[] uf, int[] lca) {if (parent != -1) {System.arraycopy(count[parent], 0, count[node], 0, W + 1);count[node][neighbors[node].get(parent)]++;}uf[node] = node;for (int child : neighbors[node].keySet()) {if (child == parent) {continue;}tarjan(child, node, neighbors, queryArr, count, visited, uf, lca);uf[child] = node;}for (int[] pair : queryArr[node]) {int node1 = pair[0], index = pair[1];if (node != node1 && !visited[node1]) {continue;}lca[index] = find(uf, node1);}visited[node] = true;}public int find(int[] uf, int i) {if (uf[i] == i) {return i;}uf[i] = find(uf, uf[i]);return uf[i];}
}

示例:

  • 提示很重要
  • 公共子祖先
    • 如果大家是为了面试,不需要了解这个算法
    • 如果是为了蓝桥杯,建议看一下这个算法

如果大家有什么思考和问题,可以在评论区讨论,也可以私信我,很乐意为大家效劳。
好啦,今天的每日一题到这里就结束了,如果大家觉得有用,可以可以给我一个小小的赞呢,我们下期再见!

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

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

相关文章

聊聊大模型 RAG 探索之路的血泪史,一周出Demo,半年用不好

大家好&#xff0c;今天我们来继续看看 RAG 落地的一些有趣的事儿&#xff0c;从技术社群早上的讨论开始&#xff0c;喜欢技术交流的可以文末加入我们 一、从一周出Demo、半年用不好说起 最近读了读2024-傅盛开年AI大课&#xff0c;其中有讲到RAG环节&#xff0c;三张片子比较…

多路IO复用服务器——select模型和poll模型

文章目录 一、多路IO复用服务器是什么&#xff1f;二、使用原理三、种类四、select模型五、select模型优缺点六、poll模型总结 一、多路IO复用服务器是什么&#xff1f; 服务器要与客户端完成tcp连接&#xff0c;并保持连接维护可用sock。 每个都需要准备一个进程管一个sock&a…

解决Xshell连接远程linux服务器,关闭Xshell程序对应的运行程序也相应关闭的问题

1.先安装screen yum install screen 2.具体步骤 screen -S test #创建一个新的窗口&#xff0c;这个窗口关闭时程序不会关闭 java -jar test.jar #运行jar包 3.杀掉java进程后&#xff0c;重新启动java项目前要执行一下screen -S test&#xff0c;即以后启动一个项目前&#…

计算机网络(第六版)复习提纲15

第四章 网络层 处于五层体系结构的第三层 SS4.2 网际协议IP 与网际协议IPv4配套的三个协议&#xff1a; 地址解析协议ARP 网际控制报文协议ICMP 网际组管理协议IGMP 一、虚拟互联网络 1.四层次的互联设备 2.虚拟互连网络 网际协议IP使得性能各异的网络在网络层上看来好像是一…

2023.1.23 关于 Redis 哨兵模式详解

目录 引言 人工恢复主节点故障 ​编辑 主从 哨兵模式 Docker 模拟部署哨兵模式 关于端口映射 展现哨兵机制 哨兵重新选取主节点的流程 哨兵模式注意事项 引言 人工恢复主节点故障 1、正常情况 2、主节点宕机 3、程序员主动恢复 先看看该主节点还能不能抢救如果不好定…

统一异常处理

统一异常处理 统一异常处理创建一个类定义方法ControllerAdvice和ExceptionHandler注意事项 统一异常处理 创建一个类 首先,我们来创建一个类,名字随意,这里我们取名ERHandler 定义方法 在ERHandler中,我们可以定义几个类,参数用来接收各种异常,这里的异常可以是任意的,返回…

【每日一题】YACS P817:两数归零

题目描述 这是上海计算机学会竞赛P817&#xff1a;两数归零标签&#xff1a; m a p map map、二分查找给定 n n n 个整数 a 1 , a 2 , a 3 , . . . , a n a_1,a_2,a_3,...,a_n a1​,a2​,a3​,...,an​&#xff0c;请统计有多少二元组 i , j i,j i,j 满足 i < j i<j…

面试官:你可以说一说你对Jmeter元素的理解吗?下

面试官&#xff1a;你可以说一说你对Jmeter元素的理解吗&#xff1f;下 监听器配置元素CSV数据集配置HTTPCookie管理器HTTP请求默认值登录配置元素 监听器 Listeners&#xff1a;显示测试执行的结果。它们可以以不同的格式显示结果&#xff0c;例如树、表、图形或日志文件 图…

嵌入式学习-驱动

嵌入式的一些基本概念 CPU与MCU的区别 CPU&#xff08;中央处理器&#xff0c;central processing unit) 指集成了运算器、控制器、寄存器、高速缓存等功能模块的芯片&#xff0c;负责执行计算机程序指令的处理器。MCU&#xff08;单片微型计算机或单片机&#xff0c;microco…

LLM大语言模型(五):用streamlit开发LLM应用

目录 背景准备工作切记streamlit开发LLM demo开一个新页面初始化session先渲染历史消息接收用户输入模拟调用LLM 参考 背景 Streamlit是一个开源Python库&#xff0c;可以轻松创建和共享用于机器学习和数据科学的漂亮的自定义web应用程序&#xff0c;用户可以在几分钟内构建一…

DNS欺骗

DNS(域名系统)作为当前全球最大 、最复杂的分布式层次数据库系统&#xff0c;具有着开放、庞大、复杂的特性。它为全球用户提供域名解析服务&#xff0c;是互联网的重要基础设施。但由于其在设计之初未考虑安全性、人为破坏等因素 &#xff0c;DNS系统在互联网高度发达的今天面…

项目中好用的安装包

react TScript 移动端 安装脚手架&#xff0c;文件名为 xm_csdn &#xff0c;配合使用 TS npx create-react-app xm_csdn --template typescript安装 sass yarn add sass安装路由及路由类型声明文件 // 路由 yarn add react-router-dom5.3.0 // 声明文件 yarn add types/…

Ubuntu下APT下载工具(Ubuntu 下最常用的下载和安装软件方法)

前言 本篇文章记录我学习Ubuntu 下用的最多的下载工具&#xff1a; APT 下载工具&#xff0c; APT 下载工具可以实现软件自动下载、配置、安装二进制或者源码的功能。 APT 下载工具和我们前面一篇文章讲解的“install”命令结合在一起构成了 Ubuntu 下最常用的下载和安装软件方…

【代码随想录】LC 242. 有效的字母异位词

文章目录 前言一、题目1、原题链接2、题目描述 二、解题报告1、思路分析2、时间复杂度3、代码详解 前言 本专栏文章为《代码随想录》书籍的刷题题解以及读书笔记&#xff0c;如有侵权&#xff0c;立即删除。 一、题目 1、原题链接 242. 有效的字母异位词 2、题目描述 二、解题…

机器学习面试题总结1-59

目录 1.请简要介绍下SVM。 2.请简要介绍下Tensorflow的计算图。 3.请问GBDT和XGBoost的区别是什么?

刘知远团队大模型技术与交叉应用L5-BMSystem

为什么需要BMTrain&#xff1f; PLM越来越大。为了使训练更高效和廉价。我们有必要 1.分析GPU的显存去哪了&#xff1f; 2.理解GPU间的合作模式是如何的&#xff1f; 显存都去了哪里&#xff1f; CPU vs GPU CPU适合复杂逻辑运算。GPU适合大量重复的数值运算。 显存成分 1.前…

csp----寻宝!大冒险!

题目描述&#xff1a; AC代码如下&#xff1a; /*思路&#xff1a; 把A变成小块 因为B是A里的一部分 通过把A变成小块 去寻找B这样速度更快 如果AB,BA&#xff0c;说明找到了。 */#include <iostream> #include <cstring> #include <algorithm> #include …

python3-cookbook-字典排序

第一章&#xff1a;数据结构和算法 Python 提供了大量的内置数据结构&#xff0c;包括列表&#xff0c;集合以及字典。大多数情况下使用这些数据结构是很简单的。但是&#xff0c;我们也会经常碰到到诸如查询&#xff0c;排序和过滤等等这些普遍存在的问题。 因此&#xff0c;这…

【Java】初识Spring Mvc

SpringMVC_day01 今日内容 理解SpringMVC相关概念完成SpringMVC的入门案例学会使用PostMan工具发送请求和数据掌握SpringMVC如何接收请求、数据和响应结果掌握RESTful风格及其使用完成基于RESTful的案例编写 1&#xff0c;SpringMVC简介 看到SpringMVC这个名字我们会发现其中…

【人工智能】主要人工智能技术及深度学习及传统机器学习区别与联系

主要人工智能技术的基本概念和应用场景 机器学习英文简称ML是一门涉及统计学、系统辨识、逼近理论、优化理论、计算机科学、脑科学等诸多领域的交叉学科&#xff0c;主要研究计算机怎样模拟或实现人类的学习行为&#xff0c;以获取新的知识或技能&#xff0c;重新组织已有的知识…