Hdu 4547 【最近公共祖先】.cpp

题意:

  dos命令的cd操作有两个可执行方法

  cd ..    回到上一级目录

  cd 当前目录名/b/c/d     当前目录名到某一个子目录下

  

  给出你目录的关系,然后给出a b问最少经过几步可以从a走到b..

 

思路:

  求出a和b的最近公共祖先,然后分4种情况讨论

  ①. a和b有一个公共祖先c,则用 c时间戳-a的时间戳+1(1步可以直接从c到b)

  ②. a是b的祖先,则只用1步就可以到达b点

  ③. b是a的祖先,则用a的时间戳-b的时间戳

  ④. a和b是同一个点,则答案是0

 

Tips:

  求绝对值的函数还是得自己写..

  用algorithm的就wa了..

  因为algorithm里面的fabs参数和返回值都是double的..

 

Code:

  1 #include <stdio.h>

  2 #include <cstring>

  3 #include <string>

  4 #include <iostream>

  5 #include <cmath>

  6 #include <map>

  7 using namespace std;

  8 

  9 const int MAXM = 10000010;

 10 const int MAXN = 100010;

 11 

 12 int f[MAXN];

 13 int find(int x)

 14 {

 15     return f[x] == x?x:f[x] = find(f[x]);

 16 }

 17 

 18 struct Edge

 19 {

 20     int s;

 21     int to;

 22     int next;

 23     int lca;

 24 }edge[MAXM], qedge[MAXM];

 25 int head[MAXN], qhead[MAXN];

 26 int tot, qtot;

 27 

 28 void add(int s, int u)

 29 {

 30     edge[tot].to = u;

 31     edge[tot].next = head[s];

 32     head[s] = tot++;

 33 }

 34 

 35 void qadd(int s, int u)

 36 {

 37     qedge[qtot].s = s;

 38     qedge[qtot].to = u;

 39     qedge[qtot].next = qhead[s];

 40     qhead[s] = qtot++;

 41     qedge[qtot].s = u;

 42     qedge[qtot].to = s;

 43     qedge[qtot].next = qhead[u];

 44     qhead[u] = qtot++;

 45 }

 46 

 47 bool vis[MAXN];

 48 int dfn[MAXN];

 49 int ti;

 50 void LCA(int u)

 51 {

 52     f[u] = u;

 53     vis[u] = true;

 54     for (int i = head[u]; i != -1; i = edge[i].next)

 55         if (!vis[edge[i].to]) {

 56             dfn[edge[i].to] = dfn[u]+1;

 57             LCA(edge[i].to);

 58             f[edge[i].to] = u;

 59         }

 60     for (int i = qhead[u]; i != -1; i = qedge[i].next) {

 61         if (vis[qedge[i].to]) {

 62             qedge[i].lca = find(qedge[i].to);

 63             qedge[i^1].lca = qedge[i].lca;

 64         }

 65     }

 66 }

 67 

 68 int abs(int x) {

 69     return x>0?x:-x;

 70 }

 71 

 72 int main()

 73 {

 74     int in[MAXN];

 75     int T, n, q;

 76     int cnt, fa;

 77     char str1[45], str2[45];

 78     scanf("%d", &T);

 79     while (T--) {

 80         scanf("%d %d", &n, &q);

 81         map<string, int> M;

 82         cnt = 1;

 83         tot = qtot = 0;

 84         ti = 0;

 85 

 86         memset(head, 0xff, sizeof(head));

 87         memset(qhead, 0xff, sizeof(qhead));

 88         for (int i = 0; i <= n; ++i) {

 89             f[i] = i;

 90             vis[i] = false;

 91             dfn[i] = 0;

 92             in[i] = 0;

 93         }

 94         for (int i = 0; i < n-1; ++i) {

 95             scanf("%s %s", str1, str2);

 96             if (!M[str1]) M[str1] = cnt++;

 97             if (!M[str2]) M[str2] = cnt++;

 98             add(M[str2], M[str1]);

 99             in[M[str1]]++;

100         }

101         for (int i = 0; i < q; ++i) {

102             scanf("%s %s", str1, str2);

103             qadd(M[str1], M[str2]);

104         }

105         for (int i = 1; i <= n; ++i)

106             if (in[i] == 0) {

107                 fa = i;

108                 break;

109             }

110         LCA(fa);

111 

112      //   for (int i = 1; i < cnt; ++i)

113      //       printf("___%d %d\n", i, dfn[i]);

114 

115         for (int i = 0; i < qtot; ++i)

116         if (i%2 == 0) {

117           //  printf("%d %d___ %d\n", qedge[i].s, qedge[i].to, qedge[i].lca);

118          //   printf("%d_____\n", qedge[i].lca);

119        //  printf("___%d %d\n", dfn[qedge[i].s], dfn[qedge[i].lca]);

120             if (qedge[i].to == qedge[i].s) puts("0");

121             else if (qedge[i].lca == qedge[i].to) printf("%d\n", abs(dfn[qedge[i].s]-dfn[qedge[i].to]));

122             else if (qedge[i].s == qedge[i].lca) puts("1");

123             else printf("%d\n", abs(dfn[qedge[i].s]-dfn[qedge[i].lca])+1);

124         }

125     }

126     return 0;

127 }
View Code

 

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4547

你可能感兴趣的:(HDU)