牛客 Borrow Classroom
https://ac.nowcoder.com/acm/contest/5086/C
其实不难,让a堵在c到1的毕竟之路上就好了,需要注意,若是a和c同时到1号点就是no,同时到其他点就是yes。。。。坑了好久我的妈呀
代码公式含义:len a到c---1的必经路的长度,假设到x点
ans b到c加上c到x的路径长度
len == ans 则同时到了某个点
#include<cstring>
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
typedef long long ll;
const int maxn = 1e5 + 767;
struct Node {
int to;
int nxt;
}G[maxn * 2];
int head[maxn];
int z;
int n;
void add(int x, int y) {
G[++z].to = y;
G[z].nxt = head[x];
head[x] = z;
}
int dep[maxn], top[maxn], fa[maxn], siz[maxn];
int son[maxn];
int dfs1(int x, int f, int d) {
dep[x] = d;
fa[x] = f;
siz[x] = 1;
int s = 0;
for (int i = head[x]; i; i = G[i].nxt) {
int p = G[i].to;
if (p == f) continue;
dfs1(p, x, d + 1);
siz[x] += siz[p];
if (s < siz[p]) {
s = siz[p];
son[x] = p;
}
}
return 0;
}//haah
int cnt;
int dfs2(int x, int t) {
top[x] = t;
if (!son[x]) return 0;
dfs2(son[x], t);//重儿子重复利用t
for (int i = head[x]; i; i = G[i].nxt) {
int p = G[i].to;
if (p == fa[x] || p == son[x]) continue;
dfs2(p, p);//轻儿子新建t
}
return 0;
}
int LCA(int x, int y) {
while (top[x] != top[y]) {
if (dep[top[x]] < dep[top[y]]) swap(x, y);
x = fa[top[x]];
}
//现在两个点在一个重链上了
if (dep[x] > dep[y]) return y;
else return x;
return 0;
}
int get(int x, int y) {
int root = LCA(x, y);
int c = dep[x] + dep[y] - 2 * dep[root];
return c;
}
int main() {
int t;
scanf("%d", &t);
while (t--) {
int m;
scanf("%d %d", &n, &m);
z = 0;
memset(head, 0, sizeof(head));
memset(son, 0, sizeof(son));
memset(top, 0, sizeof(top));
for (int i = 1; i < n; i++) {
int x, y;
scanf("%d%d", &x, &y);
add(x, y);
add(y, x);
}
dfs1(1, -1, 1);
dfs2(1, 1);
while (m--) {
int a, b, c;
scanf("%d%d%d", &a, &b, &c);
int len = get(c, a) + get(1, a) - get(c, 1);
len /= 2;
int ans = get(b, c) + get(a, c) - len;
if (ans > len) {
cout << "YES\n";
}
else if (ans == len && get(c, 1) + get(a, 1) != get(a, c)) {
cout << "YES\n";
}
else cout << "NO" << endl;
}
}
return 0;
}
寻找真正的热爱

浙公网安备 33010602011771号