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 }

 

 

 

你可能感兴趣的:(图论)