牛客 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
";
			}
			else if (ans == len && get(c, 1) + get(a, 1) != get(a, c)) {
				cout << "YES
";
			}
			else cout << "NO" << endl;
		}
	}
	return 0;
}

  

寻找真正的热爱
原文地址:https://www.cnblogs.com/lesning/p/12656439.html