Well, this question is a little different from the previous computing path.
Multiple paths are provided for you to find out which nodes are used as the closest public ancestor and calculate the number of times the nodes are used as the closest public ancestor.
First, reading data is a little troublesome.CodeIs quite convenient.
Second, you need to find the root node and perform a deep priority search. This is the only difference in the path length. When calculating a path, starting from any node does not affect the length of the calculated path.
However, in this question, we must ensure that every recent public ancestor is correct. Why? Because, when calculating the path, it is actually a relative situation, that is, in this traversal node, the relative node is the closest public ancestor, there is no strict
This question requires the recent common ancestor, so you must first find the root node, that is, the node with zero inbound level. This is also very understandable.
For details, see the previous 2586.
# Include <stdio. h> # include <string. h> # include <stdlib. h> # define maxn 910int first [maxn], head [maxn], CNT [maxn], F [maxn]; int visited [maxn]; struct node {int Vex, next;} G [maxn * 2]; struct node1 {int Vex, next;} Q [maxn * maxn]; int find (int x) {If (x = f [x]) return f [X]; F [x] = find (F [x]); Return f [X];} void add (int v, int W, Int & J) {G [J]. vex = W; G [J]. next = first [v]; first [v] = J ++;} void Add2 (int v, int W, Int & J) {q [J]. vex = W; Q [J]. next = H EAD [v]; head [v] = J ++;} void DFS (INT v) {f [v] = V; visited [v] = 1; int I; for (I = head [v]; I! =-1; I = Q [I]. next) if (visited [Q [I]. vex]) // {CNT [find (Q [I]. vex)] ++;} for (I = first [v]; I! =-1; I = G [I]. Next) {If (! Visited [G [I]. vex]) {DFS (G [I]. vex); F [G [I]. vex] = V ;}}int main () {int m, n, I, T, V, W, J, K; int flag [maxn]; char ch; while (scanf ("% d", & N )! = EOF) {k = N; memset (first,-1, sizeof (first); memset (Head,-1, sizeof (head); memset (visited, 0, sizeof (visited); memset (CNT, 0, sizeof (CNT); memset (flag, 0, sizeof (FLAG); j = 0; while (k --) {scanf ("% d", & V); While (getchar ()! = '('); // Very good reading method scanf ("% d", & T); While (getchar ()! = '); While (t --) {scanf ("% d", & W); add (V, W, J); add (W, V, j); flag [w] = 1 ;}} scanf ("% d", & M); for (I = J = 0; I <m; I ++) {While (getchar ()! = '('); Scanf ("% d", & V, & W); While (getchar ()! = '); Add2 (V, W, J); Add2 (W, V, J);} for (I = 1; I <= N; I ++) if (flag [I] = 0) // The inbound level is 0 break; DFS (I); for (I = 1; I <= N; I ++) if (CNT [I]) printf ("% d: % d \ n", I, CNT [I]);} return 0 ;}