ABC014D 閉路

D: 閉路 - AtCoder Beginner Contest 014 | AtCoder

(null)

木に 本付け加えて出来る閉路は,つなげる 点とその 点の最小共通祖先で出来る三角形になるはずである.よって, を求めた後に,その三角形の長さを出力した.長さは を求める際に深さが出ているので,そこから出せる.

Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
#include <iostream>
#include <vector>
#include <string>
#include <cstring>
#include <algorithm>
#include <sstream>
#include <map>
#include <set>
#include <cmath>

#define REP(i,k,n) for(int i=k;i<n;i++)
#define rep(i,n) for(int i=0;i<n;i++)
#define INF 1<<30
#define pb push_back
#define mp make_pair

using namespace std;
typedef long long ll;
typedef pair<int,int> P;

vector<int> G[100005];
int root;

int parent[20][100005];
int depth[100005];

void dfs(int v, int p, int d) {
  parent[0][v] = p;
  depth[v] = d;
  rep(i, G[v].size()) {
      if(G[v][i] != p) dfs(G[v][i], v, d+1);
  }
}

void init(int V) {
  dfs(root, -1, 0);
  for(int k = 0; k + 1 < 20; k++) {
      rep(v, V) {
          if(parent[k][v] < 0) parent[k + 1][v] = -1;
          else parent[k + 1][v]= parent[k][parent[k][v]];
      }
  }
}

int lca(int u, int v) {
  if(depth[u] > depth[v]) swap(u, v);
  rep(k, 20) {
      if((depth[v] - depth[u]) >> k & 1) {
          v = parent[k][v];
      }
  }
  if(u == v) return u;
  for(int k = 20 - 1; k >= 0; k--) {
      if(parent[k][u] != parent[k][v]) {
          u = parent[k][u];
          v = parent[k][v];
      }
  }
  return parent[0][u];
}

int main() {
  int n;
  cin >> n;

  rep(i, n-1) {
      int x, y;
      cin >> x >> y;

      x--; y--;
      G[x].push_back(y);
      G[y].push_back(x);
  }

  root = 0;
  init(n);

  int Q;
  cin >> Q;

  rep(q, Q) {
      int a, b;
      cin >> a >> b;

      a--; b--;

      int par = lca(a, b);

      cout << (depth[a] - depth[par]) + (depth[b] - depth[par]) + 1 << endl;
  }

  return 0;
}
Apr 3rd, 2016