=Tree Queries CodeForces - 1328E (LCA+思维)
Posted accepting
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了=Tree Queries CodeForces - 1328E (LCA+思维)相关的知识,希望对你有一定的参考价值。
题目大意:一棵树,然后m个询问,每个询问有k个点,然后判断是否有一条路,要求这k个点要么在这条路上,要么和这条路相距为1.
题解:刚开始的思路是这样的,这条路的终点肯定是深度最深的那个点,然后用BFS找到从1到终点的路线,然后在对路径上的点和与路径直接相连的点进行判断,看这k个点是否都在其中,然后就TLE了,为什么会T呢?当这棵树成了一条链时,那么算法的复杂度就退化为O(nm)。 我们来换种思路想一下,不变的还是终点,然后如果这k个点中的一些点在从1到终点的路上,那么终点和该点的LCA应该为深度小的那个点,如果与路径的距离为1 ,那么终点和该点的LCA应该是深度小的父亲节点。
code:
#include<bits/stdc++.h> using namespace std; const int N=2e5+7; vector<int>ve[N]; int dis[N]; int fa[N][30]; bool mark[N]; int arr[N]; int bits[32]; void inint(){ bits[0]=1; for(int i=1;i<=29;i++) bits[i]=bits[i-1]<<1; } void dfs(int x,int y){ dis[x]=dis[y]+1; fa[x][0]=y; for(int i=1;i<=29;i++){ fa[x][i]=fa[fa[x][i-1]][i-1]; } for(int i=0;i<ve[x].size();i++){ if(ve[x][i]!=y){ dfs(ve[x][i],x); } } } int lca(int x,int y){ if(dis[x]<dis[y]) swap(x,y); int dif=dis[x]-dis[y]; for(int i=29;i>=0;i--){ if(dif>=bits[i]) { dif-=bits[i]; x=fa[x][i]; } } if(x==y) return x; for(int i=29;i>=0;i--){ if(dis[x]>=bits[i]&&fa[x][i]!=fa[y][i]){ x=fa[x][i];y=fa[y][i]; } } return fa[x][0]; } int main(){ inint(); int n,m; cin>>n>>m; for(int i=1;i<n;i++){ int x,y; cin>>x>>y; ve[x].push_back(y); ve[y].push_back(x); } dfs(1,0); int k,x; while(m--){ cin>>k; int pos,depth=0; for(int i=1;i<=k;i++){ cin>>arr[i]; if(dis[arr[i]]>depth){ depth=dis[arr[i]]; pos=arr[i]; } } bool flag=0; for(int i=1;i<=k;i++){ int c=lca(pos,arr[i]); if(c==fa[arr[i]][0]||c==arr[i]){ continue ; } else { flag=1; break; } } if(flag)cout<<"NO"<<endl; else puts("YES"); } return 0; }
以上是关于=Tree Queries CodeForces - 1328E (LCA+思维)的主要内容,如果未能解决你的问题,请参考以下文章
Tree and Queries CodeForces - 375D 树上莫队
Codeforces 375D D. Tree and Queries
[Codeforces375D]Tree and Queries(莫队算法)
CodeForces 825G"Tree Queries"(建树选根)