• 树链剖分求LCA


    题目描述

    如题,给定一棵有根多叉树,请求出指定两个点直接最近的公共祖先。

    输入输出格式

    输入格式:

    第一行包含三个正整数N、M、S,分别表示树的结点个数、询问的个数和树根结点的序号。

    接下来N-1行每行包含两个正整数x、y,表示x结点和y结点之间有一条直接连接的边(数据保证可以构成树)。

    接下来M行每行包含两个正整数a、b,表示询问a结点和b结点的最近公共祖先。

    输出格式:

    输出包含M行,每行包含一个正整数,依次为每一个询问的结果。

    输入输出样例

    输入样例#1: 复制
    5 5 4
    3 1
    2 4
    5 1
    1 4
    2 4
    3 2
    3 5
    1 2
    4 5
    输出样例#1: 复制
    4
    4
    1
    4
    4
    

    说明

    时空限制:1000ms,128M

    数据规模:

    对于30%的数据:N<=10,M<=10

    对于70%的数据:N<=10000,M<=10000

    对于100%的数据:N<=500000,M<=500000

     1 //2018年2月17日20:50:56 
     2 #include <iostream>
     3 #include <cstdio>
     4 #include <cstring>
     5 #include <algorithm>
     6 using namespace std;
     7 
     8 const int N = 1000001;
     9 const int M = 1000001;
    10 
    11 struct Edge{
    12     int to, len, nxt;
    13 }E[M];
    14 int cnt, fir[N], fa[N], top[N], deep[N], siz[N], son[N], val[N];
    15 
    16 void addEdge(int x, int y, int z=0){
    17     E[++cnt].to = y;
    18     E[cnt].len = z;
    19     E[cnt].nxt = fir[x];
    20     fir[x] = cnt;
    21 }
    22 
    23 void dfs1(int x){
    24     deep[x] = deep[fa[x]] + 1; siz[x] = 1;
    25     for(int i=fir[x]; i; i=E[i].nxt){
    26         int to = E[i].to;
    27         if(fa[x] != to){
    28             val[to] = E[i].len;
    29             fa[to] = x;
    30             dfs1(to);
    31             siz[x] += siz[to];
    32             if(siz[son[x]] < siz[to]) son[x] = to;
    33         }
    34     }
    35 }
    36 
    37 void dfs2(int x){
    38     if(x == son[fa[x]]) top[x] = top[fa[x]];
    39     else top[x] = x;
    40     for(int i=fir[x]; i; i=E[i].nxt)
    41         if(fa[E[i].to] == x)  
    42             dfs2(E[i].to);
    43 }
    44 
    45 int query(int x, int y){
    46     for(; top[x]!=top[y]; deep[top[x]]>deep[top[y]]?x=fa[top[x]]:y=fa[top[y]]); //注意这里有个分号!!! 
    47     return deep[x]<deep[y]?x:y;
    48 }
    49 
    50 int n, m, x, y, v, root;
    51 int main(){
    52     scanf("%d%d%d", &n, &m, &root);
    53     for(int i=1;i<n;i++){
    54         scanf("%d%d", &x, &y);
    55         addEdge(x, y);
    56         addEdge(y, x);
    57     }
    58     dfs1(root);
    59     dfs2(root);
    60     
    61     for(int i=1;i<=m;i++){
    62         scanf("%d%d", &x, &y);
    63         printf("%d
    ", query(x, y));
    64     }
    65 
    66     return 0;
    67 }
  • 相关阅读:
    SQL 基础
    MySQL 关于 only_full_group_by 限制
    sarama Kafka客户端生产者与消费者梳理
    Golang context
    常见的限流算法
    Tensorflow2 深度学习十必知
    数据结构与算法稀疏数组详解
    常用数据结构之数组
    技术人创业:失败不是成功,但反思是
    12款大家都在用的产品管理平台
  • 原文地址:https://www.cnblogs.com/sineagle/p/8452185.html
Copyright © 2020-2023  润新知