首页 > 其他分享 >loj10135.「一本通 4.4 练习 2」祖孙询问

loj10135.「一本通 4.4 练习 2」祖孙询问

时间:2022-10-27 16:46:13浏览次数:89  
标签:4.4 int 询问 两点 234 祖孙 233 loj10135 dis

SLOJ P10135. 「一本通 4.4 练习 2」祖孙询问

题目描述

已知一棵n个节点的有根树。有m个询问,每个询问给出了一对节点的编号x和y,询问x与y的祖孙关系。

输入格式

输入第一行包括一个整数n表示节点个数;

接下来n行每行一对整数对a和b表示a和b之间有连边。如果b是−1,那么a就是树的根;

第n+2行是一个整数m表示询问个数;

接下来m行,每行两个正整数x和y,表示一个询问。

输出格式

对于每一个询问,若x是y的祖先则输出1,若y是x的祖先则输出2,否则输出0。

输入数据 0

10
234 -1
12 234
13 234
14 234
15 234
16 234
17 234
18 234
19 234
233 19
5
234 233
233 12
233 13
233 15
233 19

输出数据 0

1
0
0
0
2

数据范围与提示

对于30%的数据,1≤n,m≤103

对于100%的数据,1≤n,m≤4×104,每个节点的编号都不超过4×104

思路:明显就是一道纯粹的LCA(按照惯例恶补一波),只不过判断这两点间的距离与任意一点到LCA的距离作比较,若大于,则无关,若等于,则有关,等于时再判断一下哪个深度大就是儿子。

证明:因为当两点分别在不同子树上时,两点间的距离即为两点分别到LCA的距离之和,若两点中有一点为另一点祖宗,那么两点间的距离即为深度大的那一点到祖宗的距离,所以相等时有关系,深度大的为儿子。

两点间的距离不可能小于两点分别到LCA的距离的和。

#include<bits/stdc++.h>
using namespace std;
int f[100010][20],vis[100010],dis[100010],n,q,rt;
vector<int>g[100010];
void dfs(int x,int d){
    vis[x] = 1;
    dis[x] = d;
    for(int i = 1;(1<<i)<=dis[x];i++)
        f[x][i] = f[f[x][i-1]][i-1];
    for(int i = 0;i<g[x].size();i++){
        int v = g[x][i];
        if(vis[v])continue;
        f[v][0] = x;
        dfs(v,d+1);
    }
} 
int lca(int x,int y){
    if(dis[x]<dis[y])swap(x,y);
    int k = dis[x]-dis[y];
    for(int i = 0;(1<<i)<=k;i++)
        if(k&(1<<i))
            x = f[x][i];
    if(x==y)return x;
    for(int i = 19;i>=0;i--){
        if(f[x][i]!=f[y][i])
            x = f[x][i],y = f[y][i];
    }
    return f[x][0];
}
int main(){
    scanf("%d",&n);
    for(int i = 1;i<=n;i++){
        int u,v;
        scanf("%d%d",&u,&v);
        if(v==-1){
            rt = u;
            continue;
        }
        g[u].push_back(v);
        g[v].push_back(u);
    }
    dfs(rt,0);
    scanf("%d",&q);
    for(int i = 1;i<=q;i++){
        int x,y;
        scanf("%d%d",&x,&y);
        int tmp = lca(x,y);
        if(dis[x]+dis[y]-2*dis[tmp]>dis[x]-dis[tmp]&&dis[x]+dis[y]-2*dis[tmp]>dis[y]-dis[tmp]){
            puts("0");
        }else if(dis[x]>dis[y]){
            puts("2");
        }else{
            puts("1");
        }
    }
    return 0;
}

综上所述,我是蒟蒻

2022-10-27 16:40:35

标签:4.4,int,询问,两点,234,祖孙,233,loj10135,dis
From: https://www.cnblogs.com/cztq/p/16832731.html

相关文章

  • ubuntu18.04.4 设置用root账户登录到系统
    https://blog.csdn.net/qq_35715148/article/details/107671704 ubuntu18.04.4设置用root账户登录到系统默认的Ubuntu系统在登陆界面上是不支持root用户直接登录的......
  • 超级详细Hyperledger Fabric1.4.4 环境搭建部署
    超详细的HyperledgerFabric1.4.4环境搭建部署一、系统版本://系统版本[root@ecs-344386~]# cat/etc/redhat-releaseCentOSLinuxrelease7.9.2009(Core)//内核版本......
  • Visual Components 4.4版本有哪些优势
    1、软件渲染:VisualComponents4.4新版本增加了新的渲染模式,它帮助用户看到更多的细节和外形并提供丰富和更身临其境的视觉享受。软件已经更新了光影模式并添加了能看清材料......
  • JDK-11.0.17 + Neo4j-4.4.12
    JDK安装下载地址:https://www.oracle.com/java/technologies/javase-downloads.html 注册Oracle账户,并下载,选择路径安装,将bin配置到环境变量PathNeo4j安装......
  • 【教程】解决报错“无法解析依赖项。"EntityFramework 6.4.4" 与 ' EntityFramework.z
    添加包含视图的控制器执行以上添加“包含视图的MVC5控制器(使用EntityFramework)时报错解决方案在解决方案资源管理器中找到packages.config注释掉EntityFramewo......
  • 工科数学分析 Chap 1. 习题 1.4.4
    工科数学分析Chap1.习题1.4.4Description当\(x\to0\)时,下列函数哪些是\(x\)的高阶无穷小?哪些是\(x\)的同阶或等价无穷小?哪些是\(x\)的低阶无穷小?并......
  • MongoDB 4.4 数据库参数详细说明(二) - 一般参数
    1.connPoolMaxShardedConnsPerHost**作用:**设置用于与分片通信的legacy连接池的最大大小。池的大小不会阻止创建其他连接,但是会阻止连接池保留超出此限制的连接。**默认:**2......
  • MongoDB4.4新特性-不再一起发布相关工具
    从4.4版本开始,mongoexport等相关工具不再随着数据库安装包一起发布了,将单独作为一个安装包发布​​MongoDBDatabaseToolsproject:​​(https://docs.mongodb.com/databas......
  • Q4.4.6.1. 区间最长不上升子串
    Q4.4.6.1.区间最长不上升子串BZOJ4491.我也不知道题目名字是什么差分,转化为连续区间上最长>=0或<=0的区间每个节点维护区间前缀最大值,后缀最大值,区间答案......
  • 19、Opencv4.4的仿射矩阵处理
    基本思想:深入学习一下仿射矩阵的使用和分解环境window10+Mingw32+Opencv4.4.0+Eigen这里仅说明一下Eigen库的导入方法,首先去Eigen官网下载Eigen源码,解压导入Clion工程中,修......