牛客算法周周练1 C.Borrow Classroom

思路

我们可以直接求一下 l e n 1 = d i s ( A , l c a ( A , C ) ) len1 = dis(A,lca(A,C)) l e n 2 = d i s ( C , l c a ( A , C ) ) len2 = dis(C,lca(A,C)) + d i s ( k , c ) dis(k,c)
然后比较一下2着大小,如果len1 < len2那么A可以直接在他们公共祖先那里等他。
如果len1 > len2 那么C肯定是追不上的。
如果len1 = len2 这是就要看 l c a ( A , C ) lca(A,C) 是否为1,如果为1,那么会同时到达1,会追不上。
不为1,那么就在lca那里刚好追上。

code

#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std;
const int man = 2e5+10;
#define IOS ios::sync_with_stdio(0)
template <typename T>
inline T read(){T sum=0,fl=1;int ch=getchar();
for(;!isdigit(ch);ch=getchar())if(ch=='-')fl=-1;
for(;isdigit(ch);ch=getchar())sum=sum*10+ch-'0';
return sum*fl;}
template <typename T>
inline void write(T x) {static int sta[35];int top=0;
do{sta[top++]= x % 10, x /= 10;}while(x);
while (top) putchar(sta[--top] + 48);}
template<typename T>T gcd(T a, T b) {return b==0?a:gcd(b, a%b);}
template<typename T>T exgcd(T a,T b,T &g,T &x,T &y){if(!b){g = a,x = 1,y = 0;}
else {exgcd(b,a%b,g,y,x);y -= x*(a/b);}}
#ifndef ONLINE_JUDGE
#define debug(fmt, ...) {printf("debug ");printf(fmt,##__VA_ARGS__);puts("");}
#else
#define debug(fmt, ...)
#endif
typedef long long ll;
const ll mod = 1e9+7;
vector<int>sp[man];
int fa[man][20],dis[man];


void dfs(int u,int f){
	dis[u] = dis[f] + 1;
	fa[u][0] = f;
	for(int i = 1;i < 20;i++){
		fa[u][i] = fa[fa[u][i-1]][i-1];
	}
	for(int i = 0;i < sp[u].size();i++){
		int v = sp[u][i];
		if(v==f)continue;
		dfs(v,u);
	}
}

int lca(int u,int v){
	if(dis[u]<dis[v])swap(u,v);
	for(int i = 19;i >= 0;i--){
		if(dis[fa[u][i]]>=dis[v]){
			u = fa[u][i];
		}
	}
	if(u==v)return u;
	for(int i = 19;i >= 0;i--){
		if(fa[u][i]!=fa[v][i]){
			u = fa[u][i];
			v = fa[v][i];
		}
	}
	return fa[u][0];
}
int main() {
	#ifndef ONLINE_JUDGE
		//freopen("in.txt", "r", stdin);
		//freopen("out.txt","w",stdout);
	#endif
	int t;
	cin >> t;
	while(t--){
		int n,q;
		cin >> n >> q;
		for(int i = 1;i <= n;i++)sp[i].clear();
		for(int i = 1;i < n;i++){
			int u,v;
			cin >> u >> v;
			sp[u].push_back(v);
			sp[v].push_back(u);
		}
		dis[0] = 0;
		dfs(1,0);
		while(q--){
			int a,k,c;
			cin >> a >> k >> c;
			int ac,kc;
			ac = lca(a,c);
			kc = lca(k,c);
			int diskc = dis[k] + dis[c] - 2 * dis[kc];
			int disac1 = dis[a] - dis[ac];
			int disac2 = dis[c] - dis[ac];
			//cout << disac1 << " " << diskc + disac2 << endl;
			if(disac1<diskc+disac2){
				cout << "YES\n";
			}else if(disac1==diskc+disac2){
				if(ac==1)cout << "NO\n";
				else cout <<"YES\n";
			}else cout << "NO\n";
		}
	}
	return 0;
}
原创文章 93 获赞 12 访问量 8992

猜你喜欢

转载自blog.csdn.net/weixin_43571920/article/details/105429144