You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.
# include <bits/stdc++.h>
using namespace std ;
const int N = 40010 , M = 80010 ;
//链式前向星
int e [ M ] , h [ N ] , idx , ne [ M ] ;
void add ( int a , int b ) {
e [ idx ] = b , ne [ idx ] = h [ a ] , h [ a ] = idx + + ;
}
int n ;
int depth [ N ] ;
int f [ N ] [ 16 ] ;
//树上深搜
void dfs ( int u ) {
for ( int i = h [ u ] ; ~ i ; i = ne [ i ] ) {
int j = e [ i ] ;
if ( ! depth [ j ] ) {
depth [ j ] = depth [ u ] + 1 ; //① 每个节点的深度
f [ j ] [ 0 ] = u ; //② j的父节点是u
dfs ( j ) ;
}
}
}
int lca ( int a , int b ) {
if ( depth [ a ] < depth [ b ] ) swap ( a , b ) ;
for ( int k = 15 ; k > = 0 ; k - - )
if ( depth [ f [ a ] [ k ] ] > = depth [ b ] ) a = f [ a ] [ k ] ;
if ( a = = b ) return a ;
return f [ a ] [ 0 ] ;
}
int main ( ) {
memset ( h , - 1 , sizeof h ) ; //初始化链式前向星
scanf ( " %d " , & n ) ; // n个顶点
int a , b , m , root ;
while ( n - - ) {
scanf ( " %d %d " , & a , & b ) ; //表示a和b之间有一条无向边。如果b是− 1, 那么a就是树的根
if ( b = = - 1 )
root = a ;
else
add ( a , b ) , add ( b , a ) ; //有根无向树
}
//从根开始进行处理, 根的深度是1
depth [ root ] = 1 ;
dfs ( root ) ; //从根开始深搜,目标是 ①:给每个节点标识上深度 ②:给每个节点设置上打表f[i][0]的值,其实就是他爹是谁
// dfs只解决了2^0问题, 其它的2^1,2^2,2^3,...,2^k,还需要再写循环, 自己实现, 这个顺序与bfs不一样, bfs根据深度枚举, 遇到i时, 它的依赖前序都已准备好, dfs需要全跑完再来一遍
// 这个枚举序挺烦人啊, dp枚举顺序是配合业务来的,从这个来看, 固定好2^i, 然后逐个枚举每个点号进行填充
// 所以, yxc大佬没有讲按dfs进行标识深度, 而是采用了bfs进行标识, bfs是很好理解
for ( int i = 1 ; i < = 15 ; i + + )
for ( int j = 1 ; j < = N ; j + + )
f [ j ] [ i ] = f [ f [ j ] [ i - 1 ] ] [ i - 1 ] ;
scanf ( " %d " , & m ) ;
while ( m - - ) {
scanf ( " %d %d " , & a , & b ) ;
int p = lca ( a , b ) ;
if ( p = = a )
puts ( " 1 " ) ;
else if ( p = = b )
puts ( " 2 " ) ;
else
puts ( " 0 " ) ;
}
return 0 ;
}