POJ 1470 Closest Common Ancestors LCA

http://poj.org/problem?id=1470

一个讲lca和rmq的文章,网上也可以搜到翻译:

http://www.topcoder.com/tc?d1=tutorials&d2=lowestCommonAncestor&module=Static

题意:给一棵树,询问多组lca,然后问各点作为lca被询问到的次数。

分析:第一次写倍增,很丑= =。。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<vector>
 5 using namespace std;
 6 
 7 int n, root;
 8 int f[1000], lv[1000], p[1000][12], ans[1000];
 9 vector<int> son[900];
10 int in()
11 {
12     int ret = 0;
13     char ch = getchar();
14     while(!(ch >= '0' && ch <= '9')) ch = getchar();
15     while(ch >= '0' && ch <= '9'){
16         ret = ret * 10 + ch - '0';
17         ch = getchar();
18     }
19     return ret;
20 }
21 void dfs(int x, int dep)
22 {
23     lv[x] = dep;
24     for (int i = 0; i < son[x].size(); i ++)
25         dfs(son[x][i], dep+1);
26 }
27 void work()
28 {
29     memset(p, 0, sizeof(p));
30     for (int i = 0; i <= n; i++)
31         p[i][0] = f[i];
32     for (int j = 1; (1 << j) <= n; j++){
33         for (int i = 1; i <= n; i++){
34             int tmp = p[i][j-1];
35             p[i][j] = p[tmp][j-1];
36         }
37     }
38 }
39 int lca(int x, int y)
40 {
41     if (lv[x] < lv[y]) swap(x, y);
42     int log;
43     for (log = 1; (1 << log) <= lv[x]; log++);
44     log --;
45     for (int i = log; i >= 0; i--){
46         //if (lv[x] - (1 << i) >= lv[y]) x = p[x][i];
47         int tmp = p[x][i];
48         if (tmp != 0 && lv[tmp] >= lv[y]) x = p[x][i];
49     }
50     if (x == y) return x;
51     for (int i = log; i >= 0; i--){
52         if (p[x][i] != p[y][i] && p[x][i] != 0) x = p[x][i], y = p[y][i];
53     }
54     return f[x];
55 }
56 int main()
57 {
58     while(scanf("%d", &n) != EOF)
59     {
60         memset(f, 0, sizeof(f));
61         int x, y, z;
62         for (int i = 0; i < n; i++){
63             x = in(); y = in();
64             son[x].clear();
65             for (int j = 1; j <= y; j++){
66                 z = in();
67                 f[z] = x;
68                 son[x].push_back(z);
69             }
70         }
71         for (int i = 1; i <= n; i++)
72             if (f[i] == 0) root = i, f[root] = root;
73         dfs(root, 1);
74         work();
75         int q;
76         q = in();
77         memset(ans, 0, sizeof(ans));
78         for (int i = 0; i < q; i++){
79             x = in(); y = in();
80             ans[lca(x, y)] ++;
81         }
82         for (int i = 1; i <= n; i++) if (ans[i])
83             printf("%d:%d\n", i, ans[i]);
84     }
85     return 0;
86 }

 

posted @ 2014-08-11 21:02  james47  阅读(179)  评论(0编辑  收藏  举报