• 【倍增求lca】小机房的树


    2370 小机房的树

    //讲真我觉得这题面有点恶心QAQ

    大体思路:树上的最短路径一定经过两点lca, 预处理一个dis数组, 存每个点到根节点的距离, 两点(x, y) 之间的距离即为dis[x] + dis[y] - 2*dis[lca] ;

    然后倍增求lca即可,dis数组在预处理每个点深度的时候一并处理

    日常,“妙啊”

    代码君qwq

     1 #include<cmath>
     2 #include<cstdio>
     3 #include<iostream>
     4 using namespace std;
     5 const int maxn = 500050, maxm = 500050;
     6 int n, m, s, num = 0, log2n;
     7 int head[maxm], jump[maxn][23], dep[maxn], dis[maxn];
     8 struct edge {
     9     int nxt, to, dis;
    10 }e[maxm<<1];
    11 void add(int from, int to, int dis) {
    12     e[++num].nxt = head[from];
    13     e[num].to = to;
    14     e[num].dis = dis;
    15     head[from] = num;
    16 }
    17 void dfs(int v) {
    18     for(int i = head[v]; i; i = e[i].nxt) {
    19         int u = e[i].to;
    20         if(jump[v][0] != u) {
    21             jump[u][0] = v;
    22             dep[u] = dep[v] + 1;
    23             dis[u] = dis[v]+e[i].dis;
    24             dfs(u);
    25         }
    26     }
    27 }
    28 void init() {
    29 /**/for(int i = 1; i <= log2n; i++) 
    30         for(int j = 1; j <= n; j++) 
    31             jump[j][i] = jump[jump[j][i-1]][i-1];
    32 }
    33 int LCA(int x, int y) {
    34     if(dep[x] < dep[y]) swap(x, y);
    35     int t = dep[x] - dep[y];
    36     for(int i = 0; i <= log2n; i++) {
    37         if(t&(1<<i)) x = jump[x][i];
    38     }
    39     if(x == y) return x;
    40     for(int i = log2n; i >= 0; i--) {
    41         if(jump[x][i] != jump[y][i]) {
    42             x = jump[x][i];
    43             y = jump[y][i];
    44         }
    45     }
    46     return jump[x][0];
    47 }
    48 int main() {
    49     scanf("%d", &n);
    50     for(int i = 1; i < n; i++) {
    51         int x, y, z;
    52         scanf("%d%d%d", &x, &y, &z);
    53         add(x, y, z), add(y, x, z);
    54     }    
    55     s = 0;
    56     log2n = log(n)/log(2)+1;
    57     dep[s] = 1;
    58     jump[s][0] = 0;
    59     dis[s] = 0;
    60     dfs(s);
    61     init();
    62     scanf("%d", &m);
    63     for(int i = 1; i <= m; i++) {
    64         int x, y, ans = 0, lca;
    65         scanf("%d%d", &x, &y);
    66         lca = LCA(x, y);
    67         ans = dis[x] + dis[y] - 2*dis[lca];
    68         printf("%d
    ", ans);
    69     }
    70     return 0;
    71 }

     

     

     
    总之岁月漫长,然而值得期待。
  • 相关阅读:
    Android 画直线并实现拖动
    SpringBoot整合MyBatis
    SpringBoot集成JPA
    SpringBoot整合使用JdbcTemplate
    Hadoop下WordCount程序
    Linux中Hadoop的环境搭建
    大数据初始化环境
    Hibernate根据实体类自动创建表
    自定义MVC实现登录案例
    SSH(Spring Struts2 Hibernate)框架整合(注解版)
  • 原文地址:https://www.cnblogs.com/Hwjia/p/9789084.html
Copyright © 2020-2023  润新知