详解洛谷P2912 [USACO08OCT] Pasture Walking G(牧场行走)(lca模板题)

题目

思路

一道模板题,没啥好说的,直接见代码

代码

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;
int n,q,a,to[100001][22],b,deep[100001],c,t[1000001];
struct ff
{
  int id,len;
};
vector<ff> vec[100001];
void dfs(int x,int fa,int dp,int now)//now是x的深度(不计边权,根的深度计为1) dp是x距离根节点的距离(计边权)
{
  deep[x] = now;//单独开now变量是因为边权并不影响lca的值
  t[x] = dp;
  to[x][0] = fa;
  for(int i = 0;i < vec[x].size();i++)
    if(vec[x][i].id != fa)
      dfs(vec[x][i].id,x,dp + vec[x][i].len,now + 1);
}
int lca(int x,int y)
{
  if(deep[x] < deep[y]) swap(x,y);
  for(int i = 21;i >= 0;i--)
    if(deep[to[x][i]] >= deep[y])
      x = to[x][i];
  if(x == y) return x;
  for(int i = 21;i >= 0;i--)
    if(to[x][i] != to[y][i])
    {
      x = to[x][i];
      y = to[y][i];
    }
  return to[x][0];
}
int main()
{
  cin>>n>>q;
  for(int i = 1;i < n;i++)
  {
    scanf("%d%d%d",&a,&b,&c);
    vec[a].push_back({b,c});
    vec[b].push_back({a,c});
  }
  dfs(1,0,0,1);
  for(int i = 1;i <= 21;i++)
    for(int j = 1;j <= n;j++)
      to[j][i] = to[to[j][i - 1]][i - 1]; 
  while(q--)
  {
    scanf("%d%d",&a,&b);
    int k = lca(a,b);
    printf("%d\n",t[a] + t[b] - 2 * t[k]);
    //a的深度-lca(a,b)的深度就是a到lca(a,b)的距离,b的深度-lca(a,b)的深度就是b到lca(a,b)的距离
    //加起来就是a到b的距离(因为a->b的路径必定会经过lca(a,b))
  }
  return 0;
}

结语

如果这篇文章对您要帮助的话,请点赞支持一下吖! <(^-^)>

相关推荐
Navigator_Z1 小时前
LeetCode //C - 1089. Duplicate Zeros
c语言·算法·leetcode
云泽8084 小时前
C++ 可调用对象通关指南:深度解析 Lambda 表达式、function 包装器与 bind 绑定器
开发语言·c++·算法
wlsh154 小时前
Go 迭代器
算法
语戚5 小时前
力扣 3161. 块放置查询:线段树解法(Java 实现)
java·算法·leetcode·面试·线段树·力扣·
CS创新实验室5 小时前
从顺序表到动态数组:数据结构的永恒基石与现代语言的优雅封装
数据结构·算法
Black蜡笔小新6 小时前
自动化AI算法训练服务器DLTM训推一体化平台助力农业生产管理实现安全智能化
人工智能·算法·自动化
8Qi87 小时前
LeetCode 23. 合并 K 个升序链表 —— 小顶堆(PriorityQueue)
数据结构·算法·leetcode·链表·
QiLinkOS7 小时前
《打破“用爱发电”:一种基于 Gitee 与时间戳的开源权益分配机制探索》
c语言·数据结构·c++·科技·算法·gitee·开源
松间听晚8 小时前
Agentic RL 环境和代码学习:以HGPO为例
算法
智者知已应修善业8 小时前
【51单片机用T0定时器方式1,实现0.5S的时间间隔实现第一次一个灯亮、第二次二个灯亮,直到全部灯亮,然后重复整个过程】2023-12-29
c++·经验分享·笔记·算法·51单片机