• 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  
  • 相关阅读:
    快速了解微信小程序的使用,一个根据小程序的框架开发的 todos app
    剖析简易计算器带你入门微信小程序开发
    微信第一个“小程序”亮相:不是APP胜似APP!
    hello-weapp 微信小程序最简示例教程
    微信小程序剖析【下】:运行机制
    微信小程序「官方示例代码」浅析【上】
    微信小程序开发:Flex布局
    一个HTML5老兵坦言:我们真的需要“小程序”么?
    迅雷首席架构师刘智聪:微信小程序的架构与系统设计的几点观感
    微信小程序开发:http请求
  • 原文地址:https://www.cnblogs.com/AaronChang/p/12203298.html
Copyright © 2020-2023  润新知