http://162.105.81.212/JudgeOnline/problem?id=1470 #include <iostream> #define MAXN 1000 using namespace std ; int par[MAXN] , depth[MAXN] , n , ans[MAXN] ; void Readin () { int i , j , m , v , w ; memset (par , -1 , sizeof (par)) ; memset (depth , 0 , sizeof (depth)) ; memset (ans , 0 , sizeof (ans)) ; for (i = 0 ; i < n ; i ++) { scanf ("%d:(%d)" , &v , &m) ; for (j = 0 ; j < m ; j ++) { scanf ("%d" , &w) ; par[w] = v ;//指向该结点的前驱 } } } int Find (int i) { if (par[i] == -1 || depth[i]) return depth[i] ; depth[i] = Find (par[i]) + 1 ; return depth[i] ; } void GetDepth () { int i , j ; for (i = 1 ; i <= n ; i ++) Find (i) ; } void Comp () { int v , w , m , i ; scanf ("%d" , &m) ; while (m --) { scanf (" (%d%d)" , &v , &w) ; while (depth[v] > depth[w]) v = par[v] ; while (depth[v] < depth[w]) w = par[w] ;//使两结点分别向根推进直到深度相等 while (v != w)//寻找他们公共祖先 { v = par[v] ; w = par[w] ; } ans[v] ++ ; } for (i = 1 ; i <= n ; i ++) if (ans[i]) printf ("%d:%d/n" , i , ans[i]) ; } int main () { while (scanf ("%d" , &n) != EOF) { Readin () ; GetDepth () ;//计算每个结点的深度 Comp () ; } return 0 ; }