hrbustOJ 1373Leyni, LOLI and Leaders(图论)

摘自:http://acm.hrbust.edu.cn/hcpc2012/index.php?act=showpost&p=15

本题是图论题

根据题意,判断一颗树中,某个点是否是另一个点的后裔。根据递归函数的入栈出栈时间戳特点(即子结点的入栈时间戳要晚于自己,而且子节点的出栈时间戳要早于自己)或者括号定理在O(N)内预处理一遍图,即可在O(1)时间完成每次查询。

d[x]表示深度优先搜索中x的访问时间戳

f[x]表示深度优先搜索中x的结束访问时间戳

如果d[u] < d[v] < f[v] < f[u],那么vu的后裔。

 

 1 #include <cstdio>
 2 #include <cstdlib>
 3 #include <iostream>
 4 
 5 using namespace std;
 6 
 7 const int N = 100005;
 8 
 9 bool color[N];
10 int d[N], f[N], times;
11 struct edge {
12     int v;
13     edge *next;
14     edge(int vv, edge *p) {
15         v = vv;
16         next = p;
17     }
18 };
19 
20 struct graph {
21     edge *link;
22 }G[N];
23 
24 void initG(int n) {
25     for (int i=1; i<=n; ++i) G[i].link = NULL;
26 }
27 
28 void buildG(int u, int v) {
29     edge *p = new edge(v, G[u].link);
30     G[u].link = p;
31 }
32 
33 void dfsVisit(int u) {
34     color[u] = true;
35     d[u] = times = times + 1;
36     for (edge *p=G[u].link; p; p=p->next) {
37         if (!color[p->v]) dfsVisit(p->v);
38     }
39     f[u] = times = times + 1;
40 }
41 
42 void dfs(int n, int s) {
43     for (int i=1; i<=n; ++i) color[i] = false;
44     times = 0;
45     for (edge *p=G[s].link; p; p=p->next) {
46         if (!color[p->v]) dfsVisit(p->v);
47     }
48 }
49 
50 void del(edge *p) {
51     if (!p) return ;
52     del(p->next);
53     delete p;
54 }
55 
56 int main() {
57     int t;
58     scanf ("%d", &t);
59     while (t--) {
60         int q, n, u, v, s;
61         scanf ("%d", &n);
62         initG(n);
63         for (int i=1; i<=n; ++i) {
64             scanf ("%d", &u);
65             if (u) buildG(u, i);
66             else s = i;
67         }
68         buildG(s, s);
69         dfs(n, s);
70         scanf ("%d", &q);
71         while (q--) {
72             scanf ("%d%d", &u, &v);
73             if (d[u] < d[v] && f[v] < f[u]) printf ("%d>%d\n", u, v);
74             else if (d[v] < d[u] && f[u] < f[v]) printf ("%d<%d\n", u, v);
75             else printf ("%d<>%d\n", u, v);
76         }
77         for (int i=1; i<=n; ++i) del(G[i].link);
78     }
79     return 0;
80 }

 

 

 

posted on 2012-04-27 17:18  Try86  阅读(160)  评论(0)    收藏  举报