CD operation
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)
Total Submission (s): 325 Accepted Submission (s): 90
Problem Description
In Windows, we can use cmd to run some DOS functions. CD is an interesting command. Through the CD operation, we can change the current directory.
Here we can simplify the problem. Assume that there is only one root directory and there are only two CD operations:
1. CD current directory name \... \ target directory name (several directories can be contained in the middle to ensure that the target directory can be reached through an absolute path)
2. CD .. (return the parent directory of the current directory)
The current directory and a target directory are provided. How many CD operations are required at least to change the current directory to the target directory?
Input
The first line of the input data contains an integer T (T <= 20), indicating the number of samples;
In each example, the first line is two integers N and M (1 <= N, M <= 100000), indicating that there are N directories and M inquiries;
Next, two directories in each row in the N-1 line named a B (the directory name is A string containing only numbers or letters and less than 40), indicating that the parent directory of A is B.
The last M row contains two directories named a B, which indicates the minimum number of CD operations required to change the current directory from A to B.
The data guarantee is valid. There must be a root directory, and each directory can be accessed from the root directory.
Output
Output the results of each query. The output of each query occupies one row.
Sample Input
2
3 1
B
C
B C
3 2
B
C B
A C
C
Sample Output
2
1
2
Source
2013 Jinshan xishanju creative game program challenge-Preliminary Round (1)
Recommend
Liuyiding
[Cpp]
# Include <cstdio>
# Include <cstring>
# Include <map>
# Include <iostream>
# Include <string>
# Include <vector>
# Include <algorithm>
Using namespace std;
# Define N 100010
# Define M 30
Int f [N] [M], d [N], w;
Map <string, int>;
Vector <int> ch [N];
Void dfs (int x) {// obtain the depth of all nodes
D [x] = d [f [x] [0] + 1;
// For (int I = 1; I <M; I ++) f [x] [I] = f [f [x] [I-1] [I-1]; // multiply the ancestor
For (int I = ch [x]. size ()-1; I> = 0; I --)
Dfs (ch [x] [I]); // traverse the Son
}
Int lca (int x, int y) {// returns the minimum common ancestor of x and y.
If (d [x] <d [y]) swap (x, y); // ensure that the depth of x is not less than y
/* For (int k = 1, I = M-1; I> = 0; I --)
If (k <I) <= d [x]-d [y]) x = f [x] [I]; */
/*
Int k = d [x]-d [y];
For (int I = 0; I <M; I ++)
If (1 <I) & k)
X = f [x] [I]; */
For (int I = M-1; I> = 0; I --)
X = d [f [x] [I]> = d [y]? F [x] [I]: x;
If (x = y) return x; // x = y is the minimum common ancestor.
For (int I = M-1; I> = 0; I --)
If (f [x] [I]! = F [y] [I]) {
X = f [x] [I]; y = f [y] [I];
}
Return f [x] [0];
}
Int main (){
Int n, m, I, j, T;
Int x, y;
String A, B;
Scanf ("% d", & T );
While (T --){
A. clear ();
W = 1;
Memset (d, 0, sizeof (d ));
Memset (f, 0, sizeof (f ));
Memset (ch, 0, sizeof (ch ));
Scanf ("% d", & n, & m );
For (I = 1; I <n; I ++ ){
Cin> A> B;
If (x = a [A]) = 0) a [A] = x = w ++;
If (y = a [B]) = 0) a [B] = y = w ++;
Ch [y]. push_back (x );
F [x] [0] = y;
}
For (I = 1; I <w; I ++)
If (f [I] [0] = 0) {// find the root Traversal
Dfs (I); break;
}
For (int I = 1; I <M; I ++)
For (x = 1; x <= n; x ++)
F [x] [I] = f [f [x] [I-1] [I-1]; // multiply ancestor f [I] [j] = f [I] [J-1] ^ 2
While (m --){
Cin> A> B;
X = a [A]; y = a [B];
I = lca (x, y); // locate the nearest common ancestor of x and y.
// Cout <x <"<y <" "<I <endl;
X = d [x]-d [I];
If (I! = Y) x ++;
Printf ("% d \ n", x );
}
}
Return 0;
}