0%

树上集中

给定一棵含有n个节点的树,边长都为1.

有m个询问,每次询问,给定两个点A和B

询问有多少个点到A和B的距离相同。。

输入描述:

第一行一个整数n
接下来n-1,每行两个整数,表示树上的一条边。
接下来一个整数m,表示询问个数。
接下来m行,每行两个整数A和B,表示询问树上有多少个点到A和距离与到B的距离相同
n,m<=10^5

输出描述:

对于每个询问,输出一个整数

示例1
输入

4
1 2
2 3
2 4
2
1 2
1 3
输出

输出

0
2

shushangjizhong.cppview raw
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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
#include <bits/stdc++.h>
using namespace std;
#define F first
#define S second
#define MP make_pair
#define all(x) (x).begin(), (x).end()
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
const double EPS = 1e-9;
const double PI = acos(-1.0);
const int MOD = 1000 * 1000 * 1000 + 7;
const int INF = 2000 * 1000 * 1000;
const int MAXN = 100010;
const int LG = 30;
template <typename T>
inline T sqr(T n) {
return n * n;
}
vector <int> g[MAXN];
int n, x, y;
int depth[MAXN], size[MAXN], anc[MAXN][LG];
int tin[MAXN], tout[MAXN], timer;
int q, a, b;
void dfs(int v, int par = 1, int d = 0) {
depth[v] = d;
size[v] = 1;
tin[v] = timer++;
anc[v][0] = par;
for (int i = 1; i < LG; i++) {
anc[v][i] = anc[anc[v][i - 1]][i - 1];
}
for (size_t i = 0; i < g[v].size(); i++) {
int to = g[v][i];
if (to != par) {
dfs(to, v, d + 1);
size[v] += size[to];
}
}
tout[v] = timer++;
}
bool ancestor(int a, int b) {
return tin[a] <= tin[b] && tout[b] <= tout[a];
}
int go_up(int a, int b) {
for (int i = LG - 1; i >= 0; i--) {
if (!ancestor(anc[a][i], b)) {
a = anc[a][i];
}
}
return a;
}
int lca(int a, int b) {
int result = -1;
if (ancestor(a, b)) {
result = a;
} else if (ancestor(b, a)) {
result = b;
} else {
result = anc[go_up(a, b)][0];
}
return result;
}
int query(int a, int b) {
int l = lca(a, b);
int result = -1;
if (a == b) {
result = n;
} else if (depth[a] - depth[l] == depth[b] - depth[l]) {
a = go_up(a, l);
b = go_up(b, l);
result = n - size[a] - size[b];
} else {
if (depth[a] < depth[b]) {
swap(a, b);
}
int to = a;
int dist = depth[a] + depth[b] - 2 * depth[l];
if (dist % 2 == 1) {
result = 0;
} else {
dist /= 2;
for (int i = LG - 1; i >= 0; i--) {
if (depth[a] - depth[anc[to][i]] < dist) {
to = anc[to][i];
}
}
int mid = anc[to][0];
result = size[mid] - size[to];
}
}
return result;
}
int main() {
freopen("data0.in", "r", stdin);
freopen("data0.out", "w", stdout);

scanf("%d", &n);
for (int i = 0; i < n - 1; i++) {
scanf("%d%d", &x, &y);
g[x].push_back(y);
g[y].push_back(x);
}
dfs(1);
scanf("%d", &q);
while (q--) {
scanf("%d%d", &a, &b);
printf("%d\n", query(a, b));
}

return 0;
}