zoukankan      html  css  js  c++  java
  • hdu 4547 (LCA 倍增法)

    中文题就不解释了。

    简单LCA,就是求第一个点到LCA的距离,在判断第二个点是不是LCA,不是答案再加一就可。至于求距离的话直接利用倍增法的parent数组拆成二进制复杂度为logn。

    代码如下:

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstdlib>
      4 #include <cmath>
      5 #include <cstring>
      6 #include <algorithm>
      7 #include <queue>
      8 #include <stack>
      9 #include <vector>
     10 #include <set>
     11 #include <map>
     12 #define MP(a, b) make_pair(a, b)
     13 #define PB(a) push_back(a)
     14 
     15 using namespace std;
     16 
     17 typedef long long ll;
     18 typedef pair<int ,int> pii;
     19 typedef pair<unsigned int, unsigned int> puu;
     20 typedef pair<int ,double> pid;
     21 typedef pair<ll, int> pli;
     22 
     23 const int INF = 0x3f3f3f3f;
     24 const double eps = 1e-6;
     25 const int LEN = 100010;
     26 const int LOG_LEN = 22;
     27 vector<int> Map[LEN];
     28 map<string, int> mp;
     29 int ind[LEN], n ,m, root, depth[LEN], parent[LOG_LEN][LEN];
     30 
     31 void dfs(int v, int p, int d){
     32     parent[0][v] = p;
     33     depth[v] = d;
     34     for(int i=0; i<Map[v].size(); i++){
     35         if(Map[v][i]!=p) dfs(Map[v][i], v, d+1);
     36     }
     37 }
     38 
     39 void init(int n)
     40 {
     41     dfs(root, -1, 0);
     42     for(int k=0; k+1<LOG_LEN; k++){
     43         for(int i=0; i<n; i++){
     44             if(parent[k][i]<0) parent[k+1][i] = -1;
     45             else parent[k+1][i] = parent[k][parent[k][i]];
     46         }
     47     }
     48 }
     49 
     50 int lca(int u, int v)
     51 {
     52     int ret = 0;
     53     if(depth[u]>depth[v])swap(u, v);
     54     for(int k=0; k<LOG_LEN; k++){
     55         if((depth[v]-depth[u]) >> k & 1) v = parent[k][v];
     56     }
     57     if(u==v) return u;
     58     for(int k=LOG_LEN-1; k>=0; k--){
     59         if(parent[k][u]!=parent[k][v]){
     60             u = parent[k][u];
     61             v = parent[k][v];
     62         }
     63     }
     64     return parent[0][v];
     65 }
     66 
     67 int solve(int v, int p){
     68     int ret = 0;
     69     for(int i=LOG_LEN-1; i>=0; i--)
     70         if(parent[i][v]!=-1 && depth[parent[i][v]]>=depth[p]){
     71             v = parent[i][v];
     72             ret+=(1<<i);
     73         }
     74     return ret;
     75 }
     76 
     77 int main()
     78 {
     79 //    freopen("in.txt", "r", stdin);
     80 
     81     int T, a, b;
     82     char va[110], vb[110];
     83     scanf("%d", &T);
     84     while(T--){
     85         for(int i=0; i<LEN; i++)Map[i].clear();
     86         mp.clear();
     87         memset(ind, 0, sizeof ind);
     88         scanf("%d%d", &n, &m);
     89         int vcnt = 0;
     90         for(int i=0; i<n-1; i++){
     91             scanf("%s%s", va, vb);
     92             if(!mp.count(va)) mp[va] = vcnt++;
     93             if(!mp.count(vb)) mp[vb] = vcnt++;
     94             ind[mp[va]] ++;
     95             Map[mp[va]].PB(mp[vb]);
     96             Map[mp[vb]].PB(mp[va]);
     97         }
     98         for(int i=0; i<n; i++)if(!ind[i]){root = i;break;}
     99         init(n);
    100         for(int i=0; i<m; i++){
    101             scanf("%s%s", va, vb);
    102             int lv = lca(mp[va], mp[vb]);
    103             printf("%d
    ", solve(mp[va], lv)+(lv==mp[vb]?0:1));
    104         }
    105     }
    106     return 0;
    107 }
    View Code
    奔跑吧!少年!趁着你还年轻
  • 相关阅读:
    【Linux】- 文件基本属性
    【Linux】- mv命令
    【Linux】- 守护进程supervisor安装使用
    【Linux】- rm命令
    【Linux】- 开启远程连接
    【Redis】- 安装为windows服务
    Apache2.4 与 php7.1.6的链接
    apache2.4 的安装
    MySQL v5.7.18 版本解压安装
    网站系统消息表设计
  • 原文地址:https://www.cnblogs.com/shu-xiaohao/p/3529904.html
Copyright © 2011-2022 走看看