倍增LCA,LeetCode 2846. 边权重均等查询

目录

一、题目

1、题目描述

2、接口描述

3、原题链接

二、解题报告

1、思路分析

2、复杂度

3、代码详解


一、题目

1、题目描述

现有一棵由 n 个节点组成的无向树,节点按从 0n - 1 编号。给你一个整数 n 和一个长度为 n - 1 的二维整数数组 edges ,其中 edges[i] = [ui, vi, wi] 表示树中存在一条位于节点 ui 和节点 vi 之间、权重为 wi 的边。

另给你一个长度为 m 的二维整数数组 queries ,其中 queries[i] = [ai, bi] 。对于每条查询,请你找出使从 aibi 路径上每条边的权重相等所需的 最小操作次数 。在一次操作中,你可以选择树上的任意一条边,并将其权重更改为任意值。

注意:

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

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

2、接口描述

复制代码
cpp 复制代码
class Solution {
public:
    vector<int> minOperationsQueries(int n, vector<vector<int>>& edges, vector<vector<int>>& queries) {
        
    }
};

3、原题链接

2846. 边权重均等查询


二、解题报告

1、思路分析

关于ST表见:高级搜索------ST表,离线RMQ问题-CSDN博客

关于倍增法求LCA见:LCA算法-倍增算法-CSDN博客

对于树中任意两个点之间的路径我们都可以转化为两点各自到lca的路径拼接,所以这是一道典型的lca问题

所以不难求出a到b的路径,那么最小操作次数怎么求呢?对于路径上的边权我们发现取值在[1,26]之间,如果路径上边权的众数出现次数为k,那么最小操作次数就是len(path) - k

因而我们先求LCA,然后对于每个查询我们找出k,然后该查询的答案就是len(path) - k

len(path) = depth(x) +depth(y) - depth(lca) * 2

那么如何求出现次数最多的边权呢?

其实也能用倍增法解决

我们开一个数组cnt[x][i][w],表示节点x向上2^i次方层路径上的边权为w的边数,我们怎么预处理cnt[][][]呢?

在LCA预处理过程中更新即可,我们发现cnt[x][i][w] = cnt[x][i - 1][w] + cnt[fa[x][i - 1]][i - 1][w]

显然也能用倍增法解决

然后后面查询lca的时候记录路径上出现次数最多的边权即可

2、复杂度

时间复杂度: O(U(n + m)logn)空间复杂度:O(Unlogn)

3、代码详解

复制代码
cpp 复制代码
typedef pair<int, int> pii;
int f[10010][15], depth[10010], cnt[10010][15][27];
class Solution
{
public:
    vector<int> minOperationsQueries(int n, vector<vector<int>> &edges, vector<vector<int>> &queries)
    {
        memset(f, 0, sizeof(f)), memset(depth, 0, sizeof(depth)), memset(cnt, 0, sizeof(cnt));
        vector<int> res;
        vector<vector<pii>> g(n + 1);
        for (auto &e : edges)
            g[e[0] + 1].emplace_back(e[1] + 1, e[2]), g[e[1] + 1].emplace_back(e[0] + 1, e[2]);
        function<void(int, int)> dfs = [&](int x, int fa)
        {
            depth[x] = depth[fa] + 1 , f[x][0] = fa;
            for (int i = 1; i < 15; i++)
            {
                f[x][i] = f[f[x][i - 1]][i - 1];
                if (f[x][i - 1])
                    for (int w = 1; w <= 26; w++)
                        cnt[x][i][w] = cnt[x][i - 1][w] + cnt[f[x][i - 1]][i - 1][w];
            }
            for (auto [y, w] : g[x])
                if (y != fa)
                    cnt[y][0][w] = 1, dfs(y, x);
        };
        dfs(1, 0);
        for (auto &q : queries)
        {
            int x = q[0] + 1, y = q[1] + 1;
            int cntw[27]{0}, len = depth[x] + depth[y];
            if (depth[x] < depth[y])
                swap(x, y);
            for (int i = 14; i >= 0; i--)
                if (depth[f[x][i]] >= depth[y])
                {
                    for (int w = 1; w <= 26; w++)
                        cntw[w] += cnt[x][i][w];
                    x = f[x][i];
                }
            if (x != y)
            {
                for (int i = 14; i >= 0; i--)
                {
                    if (f[x][i] != f[y][i])
                    {
                        for (int w = 1; w <= 26; w++)
                            cntw[w] += cnt[x][i][w] + cnt[y][i][w];
                        x = f[x][i], y = f[y][i];
                    }
                }
                for (int w = 1; w <= 26; w++)
                    cntw[w] += cnt[x][0][w] + cnt[y][0][w];
                x = f[x][0];
            }
            int lca = x;
            len -= (depth[lca] << 1);
            res.emplace_back(len - *max_element(cntw + 1, cntw + 27));
        }
        return res;
    }
};
相关推荐
卷卷的小趴菜学编程17 分钟前
算法篇----二分查找
算法
2301_794461571 小时前
力扣-快乐数
算法·leetcode·职场和发展
chenyuhao20241 小时前
链表面试题9之环形链表进阶
数据结构·算法·链表·面试·c#
chenyuhao20241 小时前
链表的面试题8之环形链表
数据结构·算法·链表·面试·c#
Panesle2 小时前
Index-AniSora模型论文速读:基于人工反馈的动漫视频生成
人工智能·算法·机器学习·计算机视觉·开源·大模型·生成模型
liuzhangfeiabc2 小时前
[luogu12542] [APIO2025] 排列游戏 - 交互 - 博弈 - 分类讨论 - 构造
c++·算法·题解
晴空闲雲2 小时前
数据结构与算法-线性表-循环链表(Circular Linked List)
数据结构·算法·链表
Jolen_xie3 小时前
Pytorch分布式训练,数据并行,单机多卡,多机多卡
人工智能·算法
珹洺3 小时前
C++从入门到实战(十六)String(中)String的常用接口(构造接口,析构接口,迭代器,遍历修改,容量管理与数据访问)
开发语言·c++·算法·stl
是店小二呀4 小时前
【优选算法 | 栈】深入栈模拟题:从题型特征到实现技巧
c++·算法