1. 祖孙询问
/*
* Author: Chen_zhuozhuo
* Created Time: 2020/3/28 16:22:33
* File Name: a.cpp
*/
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <time.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> PII;
const int maxint = -1u>>1;
const int inf = 0x3f3f3f3f;
const int maxn = 4e4 + 10;
int head[maxn],cnt = 1;
int n, depth[maxn], from, to, m, a, b;
int fa[maxn][20];
struct EDGE{
int next,to;
}edge[maxn << 1];
void init(){
for(int i=0;i<maxn;i++){
head[i] = -1;
}
}
void init_depth(){
for(int i=1;i<maxn;i++){
depth[i] = inf;
}
}
void addedge(int from, int to){
edge[cnt].to = to;
edge[cnt].next = head[from];
head[from] = cnt ++;
}
void bfs(int root){
init_depth();
queue<int> Q;
depth[0] = 0, depth[root] = 1;
Q.push(root);
while(Q.size()){
int now = Q.front();
Q.pop();
for(int i=head[now]; ~i; i=edge[i].next){
int to = edge[i].to;
if(depth[to] > depth[now] + 1){
depth[to] = depth[now] + 1;
Q.push(to);
///不要忘了下边也在if语句里边
fa[to][0] = now;
for(int k = 1; k <= 15; k ++){
fa[to][k] = fa[fa[to][k - 1]][k - 1];
}
}
}
}
}
int lca(int a, int b){
if(depth[a] < depth[b]) swap(a, b);
for(int k = 15; k >= 0; k --){
if(depth[fa[a][k]] >= depth[b])
a = fa[a][k];
}
if(a == b) return a;
for(int k = 15; k >= 0; k --){
if(fa[a][k] != fa[b][k]){
a = fa[a][k];
b = fa[b][k];
}
}
return fa[a][0];
}
int main() {
//ios::sync_with_stdio(false);
//cin.tie(0);
cin>>n;
init();
int root;
for(int i=0;i<n;i++){
cin>>from>>to;
if(to == -1){
root = from;
}
else addedge(from,to), addedge(to,from);
}
bfs(root);
cin>>m;
while(m--){
cin>>a>>b;
int p = lca(a,b);
if(p == a) puts("1");
else if(p == b) puts("2");
else puts("0");
}
return 0;
}
/*
输入样例:
10
234 -1
12 234
13 234
14 234
15 234
16 234
17 234
18 234
19 234
233 19
5
234 233
233 12
233 13
233 15
233 19
输出样例:
1
0
0
0
2
*/
2. Tree Queries
题意
根为1的数,查询若干点是否在一条经过根的链上,若不在链上,与链最近距离为1也行。
题解
按深度排序,找最近公共祖先,不成立的条件是depth[a] - depth[lca] > 1 && depth[b] - depth[lca] > 1。
/*
* Author: Chen_zhuozhuo
* Created Time: 2020/3/28 16:22:33
* File Name: a.cpp
*/
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <time.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> PII;
const int maxint = -1u>>1;
const int inf = 0x3f3f3f3f;
const int maxn = 2e5 + 10;
int head[maxn],cnt = 1;
int n, depth[maxn], from, to, m, a, b, k, temp;
int fa[maxn][20];
struct EDGE{
int next,to;
}edge[maxn << 1];
bool cmp(int a, int b){
return depth[a] < depth[b];
}
void init(){
for(int i=0;i<maxn;i++){
head[i] = -1;
}
}
void init_depth(){
for(int i=1;i<maxn;i++){
depth[i] = inf;
}
}
void addedge(int from, int to){
edge[cnt].to = to;
edge[cnt].next = head[from];
head[from] = cnt ++;
}
void bfs(int root){
init_depth();
queue<int> Q;
depth[0] = 0, depth[root] = 1;
Q.push(root);
while(Q.size()){
int now = Q.front();
Q.pop();
for(int i=head[now]; ~i; i=edge[i].next){
int to = edge[i].to;
if(depth[to] > depth[now] + 1){
depth[to] = depth[now] + 1;
Q.push(to);
///不要忘了下边也在if语句里边
fa[to][0] = now;
for(int k = 1; k <= 18; k ++){
fa[to][k] = fa[fa[to][k - 1]][k - 1];
}
}
}
}
}
int lca(int a, int b){
if(depth[a] < depth[b]) swap(a, b);
for(int k = 18; k >= 0; k --){
if(depth[fa[a][k]] >= depth[b])
a = fa[a][k];
}
if(a == b) return a;
for(int k = 18; k >= 0; k --){
if(fa[a][k] != fa[b][k]){
a = fa[a][k];
b = fa[b][k];
}
}
return fa[a][0];
}
int main() {
ios::sync_with_stdio(false); cin.tie(0);
cin>>n>>m;
init();
for(int i=1;i<n;i++){
cin>>from>>to;
addedge(from,to), addedge(to,from);
}
bfs(1);
vector<int> V;
while(m--){
cin>>k;
V.clear();
while(k --){
cin>>temp;
V.push_back(temp);
}
int flag = 1;
if(k == 1){
cout<<"YES"<<endl;
continue;
}
else{
sort(V.begin(),V.end(),cmp);
for(int i=1;i<V.size();i++){
int a = V[i], b = V[i-1];
int Lca = lca(a, b);
if(depth[a] - depth[Lca] > 1 && depth[b] - depth[Lca] > 1){
flag = 0;
break;
}
}
}
if(flag)
cout<<"YES"<<endl;
else
cout<<"NO"<<endl;
}
return 0;
}
/*
inputCopy
10 6
1 2
1 3
1 4
2 5
2 6
3 7
7 8
7 9
9 10
4 3 8 9 10
3 2 4 6
3 2 1 5
3 4 8 2
2 6 10
3 5 4 7
outputCopy
YES
YES
YES
YES
NO
NO
*/