首页 > 其他分享 >【LCA 树上两点的距离 判定点是否在某条边中】洛谷P3398 仓鼠找sugar

【LCA 树上两点的距离 判定点是否在某条边中】洛谷P3398 仓鼠找sugar

时间:2024-08-04 21:39:39浏览次数:14  
标签:洛谷 anc int text sugar depth LCA return

题目链接:P3398 仓鼠找 sugar - 洛谷 | (luogu.com.cn)

题目大意:判定一棵树上的两条边是否相交

Tag:

[LCA] [树上两点间距离的计算] [如何判断与点在某条路径上]

思路:

\[\begin{align} &1.建图\\ &2.\text{dfs}然后\ 计算出每个点的深度 和计\text{anc}(i,j)\\ &3.根据树上路径唯一的性质 \quad 如果一个点在某条边上\\ &那么u到边的两端点的距离\text{dis}(a,b) = \text{dis}(a,u)+\text{dis}(u,b)\\ &\text{dis}(a,b) = \text{depth}(a)+\text{depth}(b)-2\times\text{depth}(c)\\ & 其中c=\text{LCA}(a,b) \end{align} \]

#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
const int N=2e5+9;
const int LOG = log2(N)+1;
int idx=0,head[N];
struct node{
    int to,val,next;
};
node e[N<<1];
bool vis[N];
int fa[N];
int anc[N][LOG];
int depth[N];
int n,Q;
int logn;
void add(int u,int v,int val){
    e[idx] = {v,val,head[u]};
    head[u] = idx++;
}
void bd(){
    cin>>n>>Q;
    logn = log2(n);
    memset(head,-1,sizeof(head));
    for(int i=1 ; i<=n-1 ; ++i){
        int u,v;
        cin>>u>>v;
        add(v,u,0);
        add(u,v,0);
    }
}
void dfs(int u,int fa){
    anc[u][0]=fa;
    for(int i=head[u] ; i!=-1 ; i=e[i].next){
        int v = e[i].to;
        if(v==fa) continue;
        depth[v] = depth[u] +1;
        dfs(v,u);
    }
}
void init(){
    for(int j=1 ; j<=logn ;++j){
        for(int i=1 ; i<=n; ++i){
            int v = anc[i][j-1];
            anc[i][j] = anc[v][j-1];
        }
    }
}
int LCA(int u,int v){
    if(u==v) return u;
    if(depth[v] > depth[u])
        swap(u,v);
    for(int i=logn ; i>=0; --i){
        if( depth[u] -(1<<i) >= depth[v])
            u =anc[u][i];
    }
    if(u == v) return u;
    
    for(int i=logn ; i>=0; --i){
        if(anc[u][i] != anc[v][i] ){
            u = anc[u][i];
            v = anc[v][i];
        }
    }
    return anc[u][0];
}
bool check(int a,int b,int c,int d){
    if(a==c || a==d || b==c || b==d ) return true;
    return false;
}
int dis(int a,int b){
    int c = LCA(a,b);
    return depth[a]+depth[b]-2*depth[c];
    //return abs(depth[a]-depth[c])+abs(depth[b]-depth[c]);
}
int main(){
    bd();
    dfs(1,0);
    init();
    for(int i=1 ; i<=Q ; ++i){
        int a,b,c,d;
        cin>>a>>b>>c>>d;
        if(check(a,b,c,d)) cout<<"Y"<<"\n";
        else {
            int len1 = dis(a,b);
            int len2 = dis(c,d);
            int join1 = LCA(a,b);
            int join2 = LCA(c,d);
            if( ( dis(a,join2) + dis(b,join2) ==len1 ) || ( dis(d,join1) + dis(c,join1) ==len2) )
                cout << "Y" << "\n";
            else
                cout << "N" << "\n"; // 确保输出结果
        }
    }
}

标签:洛谷,anc,int,text,sugar,depth,LCA,return
From: https://www.cnblogs.com/Phrink734/p/18339686

相关文章

  • LCA
    定义LCA:求最近公共祖先,是一个基本的树上问题首先给出一些定义公共祖先:在一颗有根树上,若F是x的祖先,同时也是y的祖先,则F为x,y的公共祖先最近公共祖先:x,y的公共祖先中深度最大的如何求简单的方法:分别从x,y出发向根节点走,打上标记,第一次相遇的节点就是LCA(x,y)复杂度O(nm),效......
  • 超好玩洛谷小游戏大全,好玩到停不下来(用洛谷的人都必须要知道,程序猿、OIer必备)
    Game啊你颓废了快点这个<tuifei break>{\color{White}\colorbox{Pink}{<tuifeibreak>}}<tuifei b......
  • 前端必知必会-HTMLCanvas图形
    文章目录HTMLCanvas图形添加JavaScript绘制一条线绘制一个圆圈绘制一个文本描边文本绘制线性渐变绘制圆形渐变绘制图像总结HTMLCanvas图形HTML<canvas>元素用于在网页上绘制图形。什么是HTMLCanvas?HTML<canvas>元素用于通过JavaScript动态绘制图形......
  • 最近公共祖先(LCA)
    lca目前主要是树剖求。不断跳到重链顶点的父亲,是\(O(\log(n))\)的时间复杂度,但实际比倍增跑得快很多。在求lca的过程中可以顺便把两点间的距离求出来,需要提前预处理len=点到重链顶点的长度。lca在树上差分用处大。下面是一些例题。P3128[USACO15DEC]MaxFlowP树......
  • 洛谷 统计天数 + 语句解析 题解
    题目:P1567统计天数P1597语句解析第一道:P1567统计天数题目描述炎热的夏日,KC非常的不爽。他宁可忍受北极的寒冷,也不愿忍受厦门的夏天。最近,他开始研究天气的变化。他希望用研究的结果预测未来的天气。经历千辛万苦,他收集了连续 N(1≤N≤10^6)天的最高气温数据。现在......
  • C++ 最小生成树 洛谷
    介绍:最小生成树是个啥?其实就像杨志一行人押送生辰纲。抛开最后生辰纲被抢的结局不谈,杨志他们需要到好几个地方,每个地方都需要花点过路费给梁山好汉们打点。比如下面就是一张城市地图:其中每两个图之间的路径长就是要给梁山好汉们打点的银子数。比如1号地点到2号地点的梁山好......
  • 洛谷P6786
    题目原题链接https://www.luogu.com.cn/problem/P6786题目描述小A有一个长度为n的序列a_1,a_2,...,a_n。他想从这些数中选出一些数b_1,b_2,...,b_k满足:对于所有i(1<=i<=k),b_i要么是序列b中的最大值,要么存在一个位置j使得b_j>b_i且b_i+b_j+g......
  • 洛谷P4554 小明的游戏
    小明的游戏题目描述小明最近喜欢玩一个游戏。给定一个n×m的棋盘,上面有两种格子#和@。游戏的规则很简单:给定一个起始位置和一个目标位置,小明每一步能向上,下,左,右四个方向移动一格。如果移动到同一类型的格子,则费用是0,否则费用是1。请编程计算从起始位置移动到目标位置的最小......
  • ORM之SqlSugar简单示例
    示例结构 下面给出示例代码,安装编码框架可扩展IDal接口定义namespaceORMRepository{///<summary>///数据库访问接口///</summary>///<typeparamname="T"></typeparam>publicinterfaceIDal<T>{///<summary&......
  • 洛谷 P1080 [NOIP2012 提高组] 国王游戏
    一道非常有挑战性的题目(~太难了~)。这题我们可以用贪心来做。思路:首先我们定义一个结构体struct,里面放的是每个人左手和右手的数字。接着我们需要一种排列方式,使得获得奖赏最多的大臣,所获奖赏尽可能的少;这句话听起来是不是听绕口?意思就是说得到奖赏数量最多,但加起来的总奖赏......