LCA与RMQ

参见topcoder的算法教程,Range Minimum Query and Lowest Common Ancestor

 

JOJ 一个题目:

2408 Beautiful girl, 题意:一颗树,给定三个顶点A、B、C,判断A与B之间的路径是否可以经过C

代码:

代码
   
     
/*
* LCA->RMQ
*/
#include
< cstdio >
#include
< vector >
#include
< cmath >
using namespace std;
#define MY_MAX 50010

vector
< int > graph[MY_MAX];

void read( int n){
int i, u, v;
for (i = 0 ; i < n; ++ i)
if ( ! graph[i].empty())
graph[i].clear();
for (i = 1 ; i < n; ++ i){
scanf(
" %d %d " , & u, & v);
graph[u].push_back(v);
graph[v].push_back(u);
}
}

int E[MY_MAX * 2 ]; // E[i] is the label of i-th visited node in the tour
int L[MY_MAX * 2 ]; // L[i] is the level of node E[i]
int H[MY_MAX]; // the index of the first occurrence of node i in E

bool visited[MY_MAX];
void DFS( int u, int d, int & k){
visited[u]
= true ;
E[k]
= u;
L[k]
= d;
H[u]
= k;
++ k;
int v;
for (size_t i = 0 ; i < graph[u].size(); ++ i){
v
= graph[u][i];
if ( ! visited[v]){
DFS(v, d
+ 1 , k);
E[k]
= u;
L[k]
= d;
++ k;
}
}
}

int M[MY_MAX * 2 ][ 20 ]; // 存储的索引
void preprocess( int a[], int n){
int i, j;
// initialize for the intervals with length 1
for (i = 0 ; i < n; ++ i)
M[i][
0 ] = i;
// compute values from smaller to bigger intervals
for (j = 1 ; 1 << j <= n; ++ j){
for (i = 0 ; i + ( 1 << j) - 1 < n; ++ i)
if (a[M[i][j - 1 ]] < a[M[i + ( 1 << (j - 1 ))][j - 1 ]])
M[i][j]
= M[i][j - 1 ];
else
M[i][j]
= M[i + ( 1 << (j - 1 ))][j - 1 ];
}
}

int RMQ( int a[], int i, int j){
if (i > j)
swap(i, j);
int k;
k
= int (log(j - i + 1 ) / log( 2.0 ));
if (a[M[i][k]] < a[M[j - ( 1 << k) + 1 ][k]])
return M[i][k];
else
return M[j - ( 1 << k) + 1 ][k];
}

int main(){
// freopen("in", "r", stdin);
int n, m, k, case_num = 1 ;
while (scanf( " %d " , & n) != EOF){
read(n);
for (k = 0 ; k < n; ++ k)
visited[k]
= false ;
k
= 0 ;
DFS(
0 , 0 , k);

preprocess(L,
2 * n - 1 );

int a, b, c;
int lab, lac, lbc;
if (case_num != 1 )
printf(
" \n " );
printf(
" Case %d:\n " , case_num ++ );

scanf(
" %d " , & m);
for (k = 0 ; k < m; ++ k){
scanf(
" %d %d %d " , & a, & b, & c);
lab
= E[RMQ(L, H[a], H[b])];
lac
= E[RMQ(L, H[a], H[c])];
lbc
= E[RMQ(L, H[b], H[c])];
if (a == c || b == c || (lab == lac && lbc == c)
|| (lab == lbc && lac == c))
printf(
" Yes\n " );
else
printf(
" No\n " );
}
}
}

 

你可能感兴趣的:(MQ)