Borrow Classroom (LCA模板)
题目链接:https://ac.nowcoder.com/acm/contest/5086/C
想法:
简单的LCA的板子题吧。
只需要先分类讨论一下:
学生的距离 < 老师的距离 , 那么肯定是追不上了
学生的距离 == 老师的距离 , 如果此时它们的 LCA 不是教务处的位置就可以,不然不可以
学生的距离 > 老师的距离 , 直接在教务处等就可以了
#pragma GCC optimize(3,"Ofast","inline")//O3优化 #pragma GCC optimize(2)//O2优化 #include <algorithm> #include <string> #include <cstring> #include <vector> #include <map> #include <stack> #include <set> #include <queue> #include <cmath> #include <cstdio> #include <iomanip> #include <ctime> #include <bitset> #include <cmath> #include <sstream> #include <iostream> #define LL long long #define ls nod<<1 #define rs (nod<<1)+1 #define pii pair<int,int> #define mp make_pair #define pb push_back #define INF 0x3f3f3f3f #define max(a,b) (a>b?a:b) #define min(a,b) (a<b?a:b) const double eps = 1e-10; const int maxn = 1e5 + 10; const int mod = 10; int sgn(double a){return a < -eps ? -1 : a < eps ? 0 : 1;} using namespace std; int head[maxn]; int cnt; int dep[maxn],f[maxn][21]; int MAXDEPTH; struct edge { int to,nxt; }e[maxn<<1]; void add_edge(int u,int v) { e[++cnt].to = v; e[cnt].nxt = head[u]; head[u] = cnt; e[++cnt].to = u; e[cnt].nxt = head[v]; head[v] = cnt; } void init() { MAXDEPTH = 20; cnt = 0; memset(f,0, sizeof(f)); memset(head,-1, sizeof(head)); } void dfs(int u,int fa) { dep[u] = dep[fa] + 1; for (int i = 1;(1 << i) <= dep[u];i++) { f[u][i] = f[f[u][i-1]][i-1]; } for (int i = head[u];~i;i = e[i].nxt) { if (e[i].to != fa) { f[e[i].to][0] = u; dfs(e[i].to,u); } } } int LCA(int u,int v) { if (dep[u] > dep[v]) swap(u,v); int hu = dep[u],hv = dep[v]; for (int det = hv - hu,i = 0;det;det >>= 1,i++) { if (det & 1) v = f[v][i]; } if (u == v) return u; for (int i = MAXDEPTH - 1;i >= 0;i--) { if (f[u][i] == f[v][i]) continue; u = f[u][i]; v = f[v][i]; } return f[u][0]; } int main() { int T; scanf("%d",&T); while (T--) { init(); int n,q; scanf("%d%d",&n,&q); for (int i = 0;i < n-1;i++) { int u,v; scanf("%d%d",&u,&v); add_edge(u,v); } dep[0] = -1; dfs(1,0); while (q--) { int a,b,c; scanf("%d%d%d",&a,&b,&c); if (b == c && b == 1) { printf("NO\n"); continue; } int dis1 = dep[b] + dep[c] - 2 * dep[LCA(b,c)] + dep[c]; int dis2 = dep[a]; if (dis1 < dis2) { printf("NO\n"); } else if (dis1 > dis2) { printf("YES\n"); } else { if (LCA(a,c) == 1) printf("NO\n"); else printf("YES\n"); } } } return 0; }