CodeForces 519E 树形DP A and B and Lecture Rooms

给出一棵树,有若干次询问,每次询问距两个点u, v距离相等的点的个数。

情况还挺多的,少侠不妨去看官方题解。^_^

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <algorithm>
  5 #include <vector>
  6 using namespace std;
  7 
  8 const int maxn = 100000 + 10;
  9 
 10 int n, Q;
 11 vector<int> G[maxn];
 12 
 13 int L[maxn];
 14 int fa[maxn];
 15 int sz[maxn];
 16 
 17 void dfs(int u)
 18 {
 19     sz[u] = 1;
 20     for(int i = 0; i < G[u].size(); i++)
 21     {
 22         int v = G[u][i];
 23         if(v == fa[u]) continue;
 24         fa[v] = u;
 25         L[v] = L[u] + 1;
 26         dfs(v);
 27         sz[u] += sz[v];
 28     }
 29 }
 30 
 31 const int logmaxn = 20;
 32 int anc[maxn][logmaxn];
 33 
 34 int ancestor(int a, int x)
 35 {
 36     if(!x) return a;
 37     for(int i = 0; (1 << i) <= x; i++)
 38         if(x & (1 << i)) a = anc[a][i];
 39 
 40     return a;
 41 }
 42 
 43 int LCA(int p, int q)
 44 {
 45     if(L[p] < L[q]) swap(p, q);
 46     int log;
 47     for(log = 1; (1 << log) <= L[p]; log++); log--;
 48     for(int i = log; i >= 0; i--)
 49         if(L[p] - (1 << i) >= L[q]) p = anc[p][i];
 50     if(p == q) return p;
 51     for(int i = log; i >= 0; i--)
 52         if(anc[p][i] && anc[p][i] != anc[q][i])
 53             p = anc[p][i], q = anc[q][i];
 54     return fa[p];
 55 }
 56 
 57 int main()
 58 {
 59     //freopen("in.txt", "r", stdin);
 60 
 61     scanf("%d", &n);
 62     for(int i = 1; i < n; i++)
 63     {
 64         int u, v; scanf("%d%d", &u, &v);
 65         G[u].push_back(v);
 66         G[v].push_back(u);
 67     }
 68 
 69     dfs(1);
 70 
 71     for(int i = 1; i <= n; i++) anc[i][0] = fa[i];
 72     for(int j = 1; (1 << j) < n; j++)
 73         for(int i = 1; i <= n; i++) if(anc[i][j-1])
 74             anc[i][j] = anc[anc[i][j-1]][j-1];
 75 
 76     scanf("%d", &Q);
 77     while(Q--)
 78     {
 79         int u, v; scanf("%d%d", &u, &v);
 80 
 81         if(u == v) { printf("%d\n", n); continue; }
 82 
 83         int l = LCA(u, v);
 84 
 85         if((L[u] + L[v] - L[l] * 2) & 1) { puts("0"); continue; }
 86 
 87         if(L[u] == L[v])
 88         {
 89             int t = L[u] - L[l];
 90             int uu = ancestor(u, t - 1), vv = ancestor(v, t - 1);
 91             printf("%d\n", n - sz[uu] - sz[vv]);
 92             continue;
 93         }
 94 
 95         if(L[u] < L[v]) swap(u, v);
 96         int t = L[u] + L[v] - L[l] * 2;
 97         int p1 = ancestor(u, t / 2);
 98         int p2 = ancestor(u, t / 2 - 1);
 99         printf("%d\n", sz[p1] - sz[p2]);
100     }
101 
102     return 0;
103 }
代码君

 

posted @ 2015-08-11 13:13  AOQNRMGYXLMV  阅读(167)  评论(0编辑  收藏  举报