zoukankan      html  css  js  c++  java
  • POJ 1330(LCA/倍增法模板)

    链接:http://poj.org/problem?id=1330

    题意:q次询问求两个点u,v的LCA

    思路:LCA模板题,首先找一下树的根,然后dfs预处理求LCA(u,v)

    AC代码:

     1 #include<iostream>
     2 #include<algorithm>
     3 #include<cmath>
     4 #include<cstring>
     5 #include<set>
     6 #include<string> 
     7 #include<vector>
     8 #include<stack>
     9 #include<queue> 
    10 using namespace std;
    11 typedef long long ll;
    12 const int maxbit = 15;
    13 const int maxn = 1e4+5;
    14 vector<int> G[maxn];
    15 int depth[maxn];
    16 int fa[maxn][maxbit];
    17 int Log[maxn];
    18 int N;
    19 void pre(){
    20     Log[0] = -1;
    21     Log[1] = 0,Log[2] = 1;
    22     for(int i = 3;i<maxn;i++) Log[i] = Log[i/2] + 1;
    23 } 
    24 void dfs(int cur,int father){//dfs预处理 
    25     depth[cur] = depth[father] + 1;//当前结点的深度为父亲结点+1 
    26     fa[cur][0] = father;//更新当前结点的父亲结点 
    27     for(int j = 1;(1<<j)<=N;j++){//倍增更新当前结点的祖先 
    28         fa[cur][j] = fa[fa[cur][j-1]][j-1];
    29     }
    30     for(int i = 0;i<G[cur].size() ;i++){
    31         if(G[cur][i] != father) {//dfs遍历 
    32             dfs(G[cur][i],cur);
    33         }
    34     }
    35 }
    36 int LCA(int u,int v){
    37     if(depth[u]<depth[v]) swap(u,v);
    38     int dist = depth[u] - depth[v];//深度差 
    39     while(depth[u]!=depth[v]){//把较深的结点u倍增到与v高度相等 
    40         u = fa[u][Log[depth[u]-depth[v]]];
    41     }
    42     if(u == v) return u;//如果u倍增到v,说明v是u的LCA 
    43     for(int i = Log[depth[u]];i>=0;i--){//否则两者同时向上倍增 
    44         if(fa[u][i]!=fa[v][i]){//如果向上倍增的祖先不同,说明是可以继续倍增 
    45             u = fa[u][i];//替换两个结点 
    46             v = fa[v][i];
    47         }
    48     }
    49     return fa[u][0];//最终结果为u v向上一层就是LCA 
    50 } 
    51 int main()
    52 {
    53     int t;
    54     pre();
    55     scanf("%d",&t);
    56     while(t--){
    57         scanf("%d",&N);
    58         int root ;
    59         int in[maxn]; 
    60         for(int i = 0;i<maxn;i++){
    61             G[i].clear() ;
    62         }
    63         memset(in,0,sizeof(in));
    64         int u,v;
    65         for(int i = 0;i<N-1;i++){
    66             scanf("%d%d",&u,&v);
    67             in[v] = 1;
    68             G[u].push_back(v);
    69             G[v].push_back(u);   
    70         }
    71         for(int i = 1;i<=N;i++){//寻树的根结点 
    72             if(in[i] == 0) {
    73                 root = i;
    74                 break;
    75             }
    76         }
    77         dfs(root,0);
    78         scanf("%d%d",&u,&v);
    79         int ans = LCA(u,v);
    80         printf("%d
    ",ans);
    81     }
    82     return 0;
    83 }
    84  
  • 相关阅读:
    关于CSS自文档的思考_css声明式语言式代码注释
    html5中contenteditable属性如果过滤标签,过滤富文本样式
    web前端工程化/构建自动化
    Python连载19-装饰器
    Java连载1-概述&常用的dos命令
    HTML连载18-id选择器与class区别&class选择器使用思路&后代选择器
    Python连载18-closure闭包解释及其注意点
    HTML连载17-id选择器&类选择器
    Python连载17-排序函数&返回函数的函数
    HTML连载16-颜色控制属性2&标签选择器
  • 原文地址:https://www.cnblogs.com/AaronChang/p/12203298.html
Copyright © 2011-2022 走看看