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 }