zoukankan      html  css  js  c++  java
  • lca 倍增法

    题目链接:https://www.luogu.org/problemnew/show/P3379

    AC代码:

     1 #include<iostream>
     2 #include<stack>
     3 #include<queue>
     4 #include<map>
     5 #include<stdio.h>
     6 #include<cstring>
     7 #include<string>
     8 #include<iomanip>
     9 #include<vector>
    10 #include<cmath>
    11 #include<algorithm>
    12 using namespace std;
    13 # define ll long long
    14 const int maxn = 500000+1010;
    15 # define inf 0x3f3f3f3f
    16 struct node
    17 {
    18     int to;
    19     int nex;
    20 } edge[maxn*2];
    21 int head[maxn*2],depth[maxn*2],father[maxn][22];
    22 int n,m,k,num;
    23 void addedge(int fr,int to)
    24 {
    25     edge[num].to=to;
    26     edge[num].nex=head[fr];
    27     head[fr]=num++;
    28 }
    29 void dfs(int u,int root)
    30 {
    31     depth[u]=depth[root]+1;
    32     father[u][0]=root;
    33     for(int i=1; (1<<i)<=depth[u]; i++)//能往上更新多少就更新多少
    34     {
    35         father[u][i]=father[father[u][i-1]][i-1];
    36     }
    37     for(int i=head[u]; i!=-1; i=edge[i].nex)
    38     {
    39         int v=edge[i].to;
    40         if(v==root)continue;
    41         dfs(v,u);
    42     }
    43 }
    44 int lca(int t1,int t2)
    45 {
    46     if(depth[t1]>depth[t2])swap(t1,t2);
    47     for(int i=20; i>=0; i--)//和下面的一样,要从小的开始凑,否则到后面会凑不出来
    48     {
    49         if(depth[t1]<=depth[t2]-(1<<i))//先调整到同一个高度
    50         {
    51             t2=father[t2][i];
    52         }
    53     }
    54     if(t1==t2)return t1;
    55     for(int i=20; i>=0; i--)
    56     {
    57         if(father[t1][i]!=father[t2][i])//一起往上找
    58         {
    59             t1=father[t1][i];
    60             t2=father[t2][i];
    61         }
    62     }
    63     return father[t1][0];
    64 }
    65 int main()
    66 {
    67     num=0;
    68     memset(head,-1,sizeof(head));
    69     int t1,t2;
    70     scanf("%d%d%d",&n,&m,&k);
    71     for(int i=1; i<=n-1; i++)
    72     {
    73         scanf("%d%d",&t1,&t2);
    74         addedge(t1,t2);
    75         addedge(t2,t1);
    76     }
    77     dfs(k,k);
    78 //    for(int i=1;i<=n;i++){
    79 //    cout<<i<<" "<<depth[i]<<endl;
    80 //    }
    81     for(int i=1; i<=m; i++)
    82     {
    83         scanf("%d %d",&t1,&t2);
    84         printf("%d
    ",lca(t1,t2));
    85     }
    86     return 0;
    87 }
    88  
  • 相关阅读:
    Android SQLite最简单demo实现(增删查改)
    最简单的自定义控件实现
    Android复杂自定义Listview实现
    Linux 下 实现 锐捷验证的方式
    Java EE学习路线
    ubuntu 12.04 配置-1
    Dream
    iOS UITextView设置富文本不能输入中文问题
    iOS UIScrollView滚动方法对比
    iOS 自定义View通知相关
  • 原文地址:https://www.cnblogs.com/letlifestop/p/10262798.html
Copyright © 2011-2022 走看看