Advertisement
double_trouble

LCA

Mar 26th, 2016
78
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.31 KB | None | 0 0
  1. //#define _CRT_SECURE_NO_WARNINGS
  2. #pragma comment(linker, "/STACK:16777216")
  3. #include <iostream>
  4. #include <cstdio>
  5. #include <vector>
  6. #include <cmath>
  7. #include <string>
  8. #include <algorithm>
  9. #include <string>
  10. #include <deque>
  11. #include <iomanip>
  12. #include <cstddef>
  13. #include <queue>
  14. #include <set>
  15.  
  16.  
  17. using namespace std;
  18.  
  19. const int inf = 1000000000;
  20.  
  21. vector <vector<pair<int, int> > > g;
  22. int used[50010], fin[50010], dist[50010];
  23. int timer = 0;
  24. vector<int> ord;
  25. int tree[10000000];
  26. int key[1000000];
  27. int unkey[1000000];
  28.  
  29. void dfs(int v)
  30. {
  31.     used[v] = 1;
  32.     key[v] = timer++;
  33.     unkey[key[v]] = v;
  34.     if (fin[v] == -1)
  35.         fin[v] = ord.size();
  36.     ord.push_back(key[v]);
  37.  
  38.     for (int i = 0; i < g[v].size(); i++)
  39.         if (!used[g[v][i].first])
  40.         {
  41.             dist[g[v][i].first] = dist[v] + g[v][i].second;
  42.             dfs(g[v][i].first);
  43.             ord.push_back(key[v]);
  44.         }
  45.     return;
  46. }
  47.  
  48. void inc(int v, int l, int r, int k)
  49. {
  50.     if (l + 1 == r)
  51.     {
  52.         tree[v] = ord[k];
  53.         return;
  54.     }
  55.  
  56.     int m = (l + r) / 2;
  57.     if (k < m)
  58.         inc(2 * v + 1, l, m, k);
  59.     else
  60.         if (k >= m)
  61.             inc(2 * v + 2, m, r, k);
  62.     tree[v] = min(tree[2 * v + 1], tree[2 * v + 2]);
  63.     return;
  64. }
  65.  
  66. int findmin(int v, int l, int r, int lv, int rv)
  67. {
  68.     if (l == lv && r == rv)
  69.         return tree[v];
  70.     int m = (l + r) / 2;
  71.     if (rv <= m)
  72.         return findmin(2 * v + 1, l, m, lv, rv);
  73.     else
  74.         if (lv >= m)
  75.             return findmin(2 * v + 2, m, r, lv, rv);
  76.     return min(findmin(2 * v + 1, l, m, lv, m), findmin(2 * v + 2, m, r, m, rv));
  77. }
  78.  
  79. int main()
  80. {
  81.     ios_base::sync_with_stdio(0);
  82.     //freopen("input.txt", "r", stdin);//freopen("output.txt", "w", stdout);
  83.     // freopen("slalom.in", "r", stdin);freopen("slalom.out", "w", stdout);
  84.    
  85.  
  86.     int n;
  87.     cin >> n;
  88.     g.resize(n);
  89.  
  90.     int u, v, d;
  91.     for (int i = 0; i < n - 1; i++)
  92.     {
  93.         cin >> u >> v >> d;
  94.         g[u].push_back(make_pair(v, d));
  95.         g[v].push_back(make_pair(u, d));
  96.     }
  97.  
  98.     fill(fin, fin + n, -1);
  99.     fill(used, used + n, 0);
  100.  
  101.     dist[0] = 0;
  102.     dfs(0);
  103.     fill(tree, tree + 10000000, inf);
  104.  
  105.     for (int i = 0; i < ord.size(); i++)
  106.     {
  107.         inc(0, 0, ord.size(), i);
  108.     }
  109.  
  110.     int m;
  111.     cin >> m;
  112.     int x, y;
  113.     for (int i = 0; i < m; i++)
  114.     {
  115.         cin >> x >> y;
  116.         if (fin[x] > fin[y])
  117.             swap(x, y);
  118.         int com = unkey[findmin(0, 0, ord.size(), fin[x], fin[y] + 1)];
  119.         cout << dist[x] +  dist[y] -  2 * dist[com] << endl;
  120.     }
  121.  
  122.     return 0;
  123. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement