zoukankan      html  css  js  c++  java
  • lightoj-1128-Greatest Parent(二分+LCA)

    传送门

    首先我要实力吐槽这个lightoj

    它给我的注册密码藏在不为人所见的地方

    注册注册了10多分钟

    qwq

    ----------------------------------------------------------------

    其次我要再吐槽一下这个难懂的题目

    全英文emm...

    百度翻译都救不了我

    (我画图花半天,才懂emm...)

    --------------------------------------------------------------

    好的

    我还是先解释一下题目吧

    最最最一开始给你一个t

    一共要整t次(t个不同的树)

    每次的根节点的编号都为0

    先给你2个数n、m

    n个节点的树

    m次询问

    接下来的n-1行

    第i行(1 <= i <= n-1)也有两个数x,y

    x为i点的父节点的编号

    y为i点的权值

    再接下来的m行为m次询问

    每行也有两个数x,y

    每次查询x的父节点中,权值大于或等于y,离x最远的节点,输出它的编号

    ----------------------------------------------------------------------------------------------------------

    基于倍增LCA思想上又用了二分

    和倍增LCA一样

    首先需要预处理出来fa[ ][ ]数组

    于是就开始二分找到最深的节点

    ---------------------------------------------------------------------------------------------------------

    #include<cstdio>
    #include<cstring>
    #define N 500100
    using namespace std;
    
    int n,m,dn[N],fa[N][25],dq,last,t,tt;
    
    inline int lca(int l,int r)
    {
        last--;
        if(l == r || dn[l] >= dq && dn[fa[l][0]] < dq)
            return l;
        while((fa[l][last] == -1) || dn[fa[l][last]] < dn[r])
            last--;
        if(dn[fa[l][last]] < dq)
            return lca(l,fa[l][last]);
        else if(dn[fa[l][last]] > dq)
            return lca(fa[l][last],r);
        return fa[l][last];
    }
    
    int main()
    {
        int t;
        scanf("%d",&t);
        int tt = t;
        while(t--)
        {
            memset(fa,-1,sizeof(fa));
            scanf("%d%d",&n,&m);
            for(int i = 1; i < n; i++)
            {
                int x ,y;
                scanf("%d%d",&x,&y);
                dn[i] = y;
                fa[i][0] = x;
            }
            dn[0] = 1;
            printf("Case %d:
    ",tt - t);
            
            for(int i = 0; i < n; i++)
            {
                for(int j=1; j <= 20; j++)
                {
                    if(fa[i][j - 1] == -1)
                        continue;//超出深度 
                    fa[i][j] = fa[fa[i][j-1]][j - 1];
                }
            }
            
            for(int i = 1; i <= m; i++)
            {
                last = 20;
                int x;
                scanf("%d%d",&x,&dq);
                printf("%d
    ",lca(x,0));
            }
        }
        return 0;
    }
  • 相关阅读:
    android 实现非GPS 手机定位
    Android 杂谈
    Android完全退出程序代码
    DB2数据库使用系统性能优化深入讨论
    DB2 数据库打算:失失最佳功能的准绳
    教你疾速驾驭DB2数据库中的相关饬令3
    教你快速把握DB2数据库中的相干命令5
    DB2中更新施行方案的几个罕见的方法2
    Oracle与DB2、MySQL取前10笔记实的比拟2
    JDBC衔接DB2、Oracle、MySQL、PostgreSQL
  • 原文地址:https://www.cnblogs.com/darlingroot/p/10606544.html
Copyright © 2011-2022 走看看