题目描述
小明负责维护公司一个奇怪的项目。这个项目的代码一直在不断分支(branch)但是从未发生过合并(merge)。
现在这个项目的代码一共有 N 个版本,编号 1 ~ N,其中 1 号版本是最初的版本。
除了 1 号版本之外,其他版本的代码都恰好有一个直接的父版本;即这 NNN 个版本形成了一棵以 1 为根的树形结构。
如下图就是一个可能的版本树:
1
/ \
2 3
\ / \
5 4 6
现在小明需要经常检查版本 x 是不是版本 y 的祖先版本。你能帮助小明吗? 输入描述
第一行包含两个整数 N,Q代表版本总数和查询总数。
以下 N - 1 行,每行包含 2 个整数 u 和 v ,代表版本 u 是版本 v 的直接父版本。
再之后 Q 行,每行包含 2 个整数 x 和 y ,代表询问版本 x 是不是版本 y 的祖先版本。
其中,1≤N≤10e5,1≤Q≤1051 \leq N \leq 10^5, 1 \leq Q \leq 10^51≤N≤105,1≤Q≤105。
输出描述
对于每个询问,输出 YES 或 NO 代表 xxx 是否是 yyy 的祖先。
输入输出样例
输入 6 5 1 2 1 3 2 5 3 6 3 4 1 1 1 4 2 6 5 2 6 4 输出 YES YES NO NO NO
AC代码
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StreamTokenizer;
import java.util.Scanner;
import java.util.Vector;
public class Main {
static Vector<Integer> v[];
static Vector<Integer> q[];
static Vector<Integer> q_id[];
static int vis[];
static int ans[];
static int fa[];// f[x] = y;x的父亲是y
static int x[];
static int find(int x) {
if (x == fa[x])
return x;
return fa[x] = find(fa[x]);
}
// v=2, 表示已经访问完了,而且还回溯了,即它的子节点已经全部访问过了
// v=1, 表示访问过,但是还没有回溯,即现在在访问它的子节点
// v=0, 表示还没有访问过
static void tarjan(int x) {
vis[x] = 1;
for(int i = 0;i < v[x].size();i++) {
int y = v[x].get(i);
if(vis[y] != 0) continue;
tarjan(y);
fa[y] = x;
}
for(int i = 0;i < q[x].size();i++) {
int y = q[x].get(i), id = q_id[x].get(i);
if(vis[y] == 2) {
ans[id] = find(y);
}
}
vis[x] = 2;
}
public static void main(String[] args) throws IOException {
Scanner cin = new Scanner(System.in);
int n = cin.nextInt();
int m = cin.nextInt();
v = new Vector[n + 5];
q = new Vector[n + 5];
q_id = new Vector[n + 5];
x = new int[n + 5];
vis = new int[n + 5];
fa = new int[n + 5];
ans = new int[m + 5];
for (int i = 1; i <= n; i++) {
v[i] = new Vector<>();
q[i] = new Vector<>();
q_id[i] = new Vector<>();
}
for(int i = 1;i <= n;i++)fa[i] = i;
for (int i = 1; i <= n - 1; i++) {
int x = cin.nextInt();
int y = cin.nextInt();
v[x].add(y);
v[y].add(x);
}
for (int i = 1; i <= m; i++) {
int a = cin.nextInt();
x[i] = a;
int b = cin.nextInt();
if(a == b) ans[i] = a;
q[a].add(b);
q[b].add(a);
q_id[a].add(i);
q_id[b].add(i);
}
tarjan(1);
for(int i = 1;i <= m;i++)
System.out.println(ans[i] == x[i] ? "YES" : "NO");
}
}