当前位置: 首页 > news >正文

DeepSeek LeetCode 3553. 包含要求路径的最小带权子图 II JavaScript实现

核心思路

本题给定的是无向带权树,树中任意两点间有且仅有一条简单路径。对于每个查询 (src1, src2, dest),包含两条路径的最小连通子图就是这两条路径的并集。

关键公式:三条路径 (src1→src2)、(src1→dest)、(src2→dest) 的并集总权重为:

```
(dist(src1, src2) + dist(src1, dest) + dist(src2, dest)) / 2
```

因为并集中的每条边在三段两两距离中恰好被计算两次。

预处理使用二进制提升(Binary Lifting) 求LCA,单次查询 O(log n)。

完整 JavaScript 实现

```javascript
/**
* @param {number[][]} edges - 边列表 [u, v, w]
* @param {number[][]} queries - 查询列表 [src1, src2, dest]
* @return {number[]} - 每个查询的最小总权重
*/
function minimumWeight(edges, queries) {
const n = edges.length + 1;
const graph = Array.from({ length: n }, () => []);

// 构建无向图
for (const [u, v, w] of edges) {
graph[u].push([v, w]);
graph[v].push([u, w]);
}

// DFS 预处理 parent 和 depth
const parent = Array(n).fill([-1, 0]);
const depth = Array(n).fill(0);

function dfs(node, par, parWeight, d) {
depth[node] = d;
parent[node] = [par, parWeight];
for (const [nei, weight] of graph[node]) {
if (nei === par) continue;
dfs(nei, node, weight, d + 1);
}
}
dfs(0, -1, 0, 0);

const lca = new LCA(n, parent, depth);
const ans = [];

for (const [src1, src2, dest] of queries) {
const d1 = lca.getDist(src1, src2);
const d2 = lca.getDist(src1, dest);
const d3 = lca.getDist(src2, dest);
ans.push((d1 + d2 + d3) / 2);
}

return ans;
}

class LCA {
constructor(n, parent, depth) {
this.maxDepth = Math.ceil(Math.log2(n)) + 1;
this.depth = depth;

// up[k][v] = v 的 2^k 级祖先
this.up = Array.from({ length: this.maxDepth }, () => Array(n).fill(-1));
// sum[k][v] = v 到其 2^k 级祖先的路径权重和
this.sum = Array.from({ length: this.maxDepth }, () => Array(n).fill(0));

// 初始化第 0 层
for (let v = 0; v < n; v++) {
this.up[0][v] = parent[v][0];
this.sum[0][v] = parent[v][1];
}

// 递推计算更高层
for (let k = 1; k < this.maxDepth; k++) {
for (let v = 0; v < n; v++) {
const mid = this.up[k - 1][v];
if (mid !== -1) {
this.up[k][v] = this.up[k - 1][mid];
this.sum[k][v] = this.sum[k - 1][v] + this.sum[k - 1][mid];
}
}
}
}

// 获取 LCA
getLCA(a, b) {
if (this.depth[a] > this.depth[b]) [a, b] = [b, a];

// 将 b 提升到与 a 同深度
let diff = this.depth[b] - this.depth[a];
for (let k = 0; k < this.maxDepth; k++) {
if ((diff >> k) & 1) {
b = this.up[k][b];
}
}

if (a === b) return a;

// 同时提升
for (let k = this.maxDepth - 1; k >= 0; k--) {
if (this.up[k][a] !== this.up[k][b]) {
a = this.up[k][a];
b = this.up[k][b];
}
}

return this.up[0][a];
}

// 获取 a 到 b 的路径权重和
getDist(a, b) {
const lca = this.getLCA(a, b);
return this._getUpSum(a, this.depth[a] - this.depth[lca]) +
this._getUpSum(b, this.depth[b] - this.depth[lca]);
}

// 获取节点 v 到其 k 级祖先的路径权重和(内部方法)
_getUpSum(v, k) {
let sum = 0;
for (let i = 0; i < this.maxDepth; i++) {
if ((k >> i) & 1) {
sum += this.sum[i][v];
v = this.up[i][v];
}
}
return sum;
}
}

// 测试用例
console.log(minimumWeight(
[[0,1,2],[1,2,3],[1,3,5],[1,4,4],[2,5,6]],
[[2,3,4],[0,2,5]]
)); // [12, 11]

console.log(minimumWeight(
[[1,0,8],[0,2,7]],
[[0,1,2]]
)); // [15]
```

复杂度分析

项目 复杂度
预处理(DFS + 二进制表) O(n log n)
单次查询 O(log n)
空间 O(n log n)

其中 n 为节点数,m 为查询数。

http://www.cnnetsun.cn/news/3388545.html

相关文章:

  • LibYAML超全教程-C语言YAML解析与生成
  • C++ STL容器选择指南:vector与list的性能对比与应用场景
  • TPS7A54 4A超低噪声LDO设计:从原理到PCB布局的工程实践
  • BaiduPCS-Go:高性能命令行网盘管理工具的5大核心技术解析
  • HoRain云--LangChain 个人知识库问答系统
  • C++ std::bind 参数绑定机制详解:从原理到实战应用
  • Unity Prefab变体:5分钟构建差异化敌人体系与性能优化实战
  • 掌握Vue3 第六章(Ref全家桶实战与避坑指南)
  • 小米智能音箱Pro体验:平衡音质与智能交互的家庭枢纽
  • 记录:hbuildx 无线真机调试,公司网络无法连接问题
  • Kilo Code接入GLM-4.6本地补全实战指南
  • DRA75x引脚配置实战:从GMAC、GPIO到eMMC的硬件设计与软件避坑指南
  • Weknora AI知识库问答系统检索指标测试方法
  • IP与IK防护:厂家必须知道的可靠性真相
  • C++高精度算法实现:从原理到工程实践,手把手构建大整数运算库
  • STM32 UART串口中断接收与状态机解析实战(一种高效稳定的解析范式)
  • TI MSP430F676x1A三相电能计量SoC:架构、低功耗设计与开发实战
  • 告别setup.py:使用pyproject.toml打造现代Python包
  • 基于STM8与DS18B20的LCD1602四线驱动温度监测系统实现
  • DLP3010芯片组应用实战:从光学设计到热管理的系统级避坑指南
  • 生产管理5M1E:人、机、料、法、环、测到底该怎么理解?
  • Unity动画事件实战:帧级精准触发游戏音效与特效
  • 实战指南|心理学实验样本量计算:从理论到实践
  • Unity Shader Graph纹理数组:性能优化与实战应用指南
  • 在YOLOv11中引入Transformer自注意力:是锦上添花还是负优化?
  • 攻克英语期刊写作:从Results到Discussion的实战解析与避坑指南
  • 从性能瓶颈到无缝融合:使用Boost.Python构建C++与Python的混合计算引擎
  • 人机识别对抗——鼠标轨迹模拟:贝塞尔曲线、噪声注入、速度变化与验证通过
  • 实战演练:利用MATLAB构建(7,4)汉明码的完整通信链路仿真
  • PyBind11 2.12 零拷贝数据交换:C++与Python高性能混合编程实践