zoukankan      html  css  js  c++  java
  • hihoCoder#1069 最近公共祖先·三

    原题地址

    根据提示用Spase Table做

    将Tree先展成List,因为数组长度等于边数的2倍,树中边数等于节点数-1,所以List数组只要开2倍节点数大小即可

    WA了几次,原来是查询的时候出现左边界大于右边界的情况,所以这种情况要颠倒一下

    代码:

     1 #include <iostream>
     2 #include <vector>
     3 #include <string>
     4 #include <map>
     5 
     6 using namespace std;
     7 
     8 #define MAX_NODE 100005
     9 
    10 int N, M;
    11 map<string, int> a2i;
    12 string i2a[MAX_NODE];
    13 int traverse_path[MAX_NODE * 2];
    14 int depth[MAX_NODE];
    15 int st[MAX_NODE * 2][32]; // 保存的是节点编号
    16 vector<int> child[MAX_NODE];
    17 int last_position[MAX_NODE];
    18 int path_length = 0;
    19 int tree_size = 0;
    20 
    21 void traverse(int r, int d) {
    22   traverse_path[path_length++] = r;
    23   depth[r] = d;
    24   for (auto c : child[r]) {
    25     traverse(c, d + 1);
    26     traverse_path[path_length++] = r;
    27   }
    28   last_position[r] = path_length - 1;
    29 }
    30 
    31 void build() {
    32   for (int i = 0; i < path_length; i++)
    33     st[i][0] = traverse_path[i];
    34 
    35   for (int j = 1; (1 << j) <= path_length; j++) {
    36     for (int i = 0; i + (1 << j) <= path_length; i++) {
    37       int a = st[i][j - 1];
    38       int b = st[i + (1 << (j - 1))][j - 1];
    39       st[i][j] = depth[a] < depth[b] ? a : b;
    40     }
    41   }
    42 }
    43 
    44 int query(int l, int r) {
    45   if (l > r)
    46     return query(r, l);
    47   int len = r - l + 1;
    48   int i = 0;
    49   while ((1 << (i + 1)) <= len)
    50     i++;
    51   int a = st[l][i];
    52   int b = st[r - (1 << i) + 1][i];
    53   return depth[a] < depth[b] ? a : b;
    54 }
    55 
    56 int main() {
    57   scanf("%d", &N);
    58   for (int i = 0; i < N; i++) {
    59     string a, b;
    60     int ai, bi;
    61     cin >> a >> b;
    62     if (a2i.find(a) == a2i.end()) {
    63       ai = a2i[a] = tree_size;
    64       i2a[ai] = a;
    65       tree_size++;
    66     }
    67     else
    68       ai = a2i[a];
    69     if (a2i.find(b) == a2i.end()) {
    70       bi = a2i[b] = tree_size;
    71       i2a[bi] = b;
    72       tree_size++;
    73     }
    74     else
    75       bi = a2i[b];
    76     child[ai].push_back(bi);
    77   }
    78 
    79   traverse(0, 0);
    80   build();
    81 
    82   scanf("%d", &M);
    83   while (M--) {
    84     string a, b;
    85     int ai, bi;
    86     cin >> a >> b;
    87     ai = a2i[a];
    88     bi = a2i[b];
    89     cout << i2a[query(last_position[ai], last_position[bi])] << endl;
    90   }
    91 
    92   return 0;
    93 }
  • 相关阅读:
    WCF 第二章 契约 异步访问服务操作
    WCF 第一章 基础 在IIS中寄宿服务
    哈希表 解释 和 实现
    ACM2010省赛总结
    hashTable实现
    c# winform 应用编程代码总结 14
    徽文化让世博更多彩
    c# winform 应用编程代码总结 15
    Socket用法详解
    IE插件技术 BHO C# IE 插件
  • 原文地址:https://www.cnblogs.com/boring09/p/4383056.html
Copyright © 2011-2022 走看看