LCA与RMQ yongmou

参见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");
}
}
}

原文地址:https://www.cnblogs.com/liyongmou/p/1800188.html