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
| #include <cstdio> #include <vector> #include <algorithm>
int fa[10005][20], dep[100005], In[10005], Out[10005], n, m, cnt; std::vector<int> G[10005]; void dfs(int u) { In[u] = ++ cnt; for (int i = 1; i <= 18; ++ i) fa[u][i] = fa[fa[u][i - 1]][i - 1]; for (int v : G[u]) if (v != fa[u][0]) fa[v][0] = u, dep[v] = dep[u] + 1, dfs(v); Out[u] = cnt; } int LCA(int u, int v) { if (dep[u] < dep[v]) u ^= v ^= u ^= v; int hhh = dep[u] - dep[v]; for (int i = 0; i <= 18; ++ i) if (hhh & 1 << i) u = fa[u][i]; if (u == v) return u; for (int i = 18; i >= 0; -- i) if (fa[u][i] != fa[v][i]) u = fa[u][i], v = fa[v][i]; return fa[u][0]; } struct Quest { int u, v, lca; inline bool operator < (const Quest a) { return dep[lca] > dep[a.lca]; } } q[50005]; struct Node { int l, r, v; } tree[40005]; void make_tree(int O, int L, int R) { tree[O].l = L, tree[O].r = R, tree[O].v = 0; if (L != R) { make_tree(O << 1, L, L + R >> 1); make_tree(O << 1 | 1, (L + R >> 1) + 1, R); } } void update(int O, int L, int R) { if (L <= tree[O].l && tree[O].r <= R) { tree[O].v = 1; return; } int mid = tree[O].l + tree[O].r >> 1; if (L <= mid) update(O << 1, L, R); if (mid < R) update(O << 1 | 1, L, R); tree[O].v = tree[O << 1].v & tree[O << 1 | 1].v; } int query(int O, int x) { if (tree[O].v) return 1; if (tree[O].l == tree[O].r) return tree[O].v; int mid = tree[O].l + tree[O].r >> 1; if (x <= mid) return query(O << 1, x); else return query(O << 1 | 1, x); }
int main() { while (scanf("%d", &n) == 1) { ++ n; make_tree(1, 1, n); cnt = 0; int ans = 0; for (int i = 1; i <= n; ++ i) G[i].clear(); for (int i = 1; i < n; ++ i) { int u, v; scanf("%d%d", &u, &v); ++ u, ++ v; G[u].push_back(v), G[v].push_back(u); } dfs(1); scanf("%d", &m); for (int i = 1; i <= m; ++ i) scanf("%d%d", &q[i].u, &q[i].v), q[i].lca = LCA(++ q[i].u, ++ q[i].v); std::sort(q + 1, q + m + 1); for (int i = 1; i <= m; ++ i) { if (query(1, In[q[i].u]) || query(1, In[q[i].v])) continue; else ++ ans, update(1, In[q[i].lca], Out[q[i].lca]); } printf("%d\n", ans); } return 0; }
|