Codeforces Round #629 (Div.3)E Tree Queries(最近公共祖先LCA)

Codeforces Round #629E Tree Queries

You are given a rooted tree consisting of n vertices numbered from 1 to n. The root of the tree is a vertex number 1.

A tree is a connected undirected graph with n−1 edges.

You are given m queries. The i-th query consists of the set of ki distinct vertices vi[1],vi[2],…,vi[ki]. Your task is to say if there is a path from the root to some vertex u such that each of the given k vertices is either belongs to this path or has the distance 1 to some vertex of this path.

大概题意:能否在树上找到一条路径使得给出的k个结点在这条路径上或者到路径的距离为1
传送门:Tree Queries

思路分析:

找到给出的k个节点中最深的节点,若满足题意则k个结点中最深的结点和第i个结点的最近公共祖先为第i个祖先的父结点或者就是第i个结点本身。

代码实现:

#include<iostream>
#include<vector>
using namespace std;
const int MAX_N=2e5+5;
const int MAX_BIT=21;
vector<int>G[MAX_N];
int depth[MAX_N],father[MAX_N][MAX_BIT],lg[MAX_N];
int n;int num[MAX_N];
void dfs(int nowp,int fa){
    
    
	depth[nowp]=depth[fa]+1;
	father[nowp][0]=fa;
	for(int i=1;i<=lg[depth[nowp]];++i)
		father[nowp][i]=father[father[nowp][i-1]][i-1];
	for(int i=0;i<G[nowp].size();++i){
    
    
		if(G[nowp][i]==fa)continue;
		else dfs(G[nowp][i],nowp);
	}
}
int LCA(int u,int v){
    
    
	if(depth[u]<depth[v])swap(u,v);
	int dep=depth[u]-depth[v];
	for(int i=0;i<MAX_BIT;++i)
		if((dep>>i)&1)u=father[u][i];
	if(u==v)return u;
	for(int i=lg[depth[u]];i>=0;i--){
    
    
		if(father[u][i]!=father[v][i]){
    
    
			u=father[u][i];
			v=father[v][i];
		}
	}
	return father[u][0];
}
int main(){
    
    
	lg[0]=-1;
	for(int i=1;i<=MAX_N;++i)
		lg[i]=lg[i>>1]+1;
	
	int v,ask;
	cin>>v>>ask;
	for(int i=1;i<=v-1;++i){
    
    
		int from,to;
		cin>>from>>to;
		G[from].push_back(to);
		G[to].push_back(from);
	}
	dfs(1,0); 
	for(int i=1;i<=ask;++i){
    
    	
		cin>>n;
		int maxdep=0,maxdep_v=0;
		for(int i=1;i<=n;++i){
    
    
			cin>>num[i];
			if(depth[num[i]]>maxdep)maxdep=depth[num[i]],maxdep_v=num[i];
		}
		int update=1;
		for(int i=1;i<=n;++i){
    
    
			if(depth[LCA(maxdep_v,num[i])]-depth[num[i]]>1||depth[LCA(maxdep_v,num[i])]-depth[num[i]]<-1)update=0;
		}
		if(update)puts("YES");
		else puts("NO");
	}
	return 0;
} 

猜你喜欢

转载自blog.csdn.net/wenyisir/article/details/105532562
今日推荐