/*
Name: tarjan 算法求 LCA
Author: Micklongen
Description: O(N + Q),N表示节点数,Q表示查询数
*/
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <algorithm>
using namespace std;
struct Node
{
int visit;
int child;
int depth;
int brother;
};
struct Node node[50010];
struct List_node
{
int index;
int node;
int next;
};
int header[50010];
struct List_node list_node[100010];
int top;
int out[50010];
int father[50010];
int find(int u)
{
return father[u] == u ? u : (father[u] = find(father[u]));
}
int merge(int u, int v)
{
int a = find(u);
int b = find(v);
if (a != b)
father[b] = a;
return 0;
}
int com_depth(int root, int depth)
{
int child, list;
node[root].depth = depth;
child = node[root].child;
father[root] = root;
while(child != -1)
{
com_depth(child, depth + 1);
merge(root, child);
child = node[child].brother;
}
node[root].visit = 1;
list = header[root];
while (list != -1)
{
if (node[list_node[list].node].visit == 1)
out[list_node[list].index] = node[find(list_node[list].node)].depth;
list = list_node[list].next;
}
return 0;
}
int main()
{
int i, j;
int v, num, inum;
int a, b;
while (scanf("%d", &num) != EOF)
{
for (i = 1; i <= num; ++i)
{
header[i] = -1;
node[i].child = -1;
node[i].visit = 0;
scanf("%d", &inum);
for (j = 1; j <= inum; ++j)
{
scanf("%d", &v);
node[v].brother = node[i].child;
node[i].child = v;
}
}
top = 0;
scanf("%d", &num);
for (i = 1; i <= num; ++i)
{
scanf("%d %d", &a, &b);
list_node[top].index = i;
list_node[top].node = b;
list_node[top].next = header[a];
header[a] = top;
++top;
list_node[top].index = i;
list_node[top].node = a;
list_node[top].next = header[b];
header[b] = top;
++top;
}
com_depth(1, 1);
for (i = 1; i <= num; ++i)
printf("%d\n", out[i]);
}
return 1;
}
|