标签:break return contest 更新 处理 log 查询 namespace wap
https://codeforces.com/contest/1328/problem/E
题目所描述的是一棵树,题中已明示1为root结点。
题目可以转化为,是否存在一条路径,满足集合中的k个点到路径的距离小于等于1?
思路:
1.首先倍增离线预处理出结点深度,便于后续在线询问LCA
2.对于每次的询问,依次扫描k个点。对于集合中的u和v两点,每次我们求出u和v的LCA,计算u和v到LCA的距离,如果u和v到LCA的距离同时大于1,那么说明无法找到一条路径,使得u和v到该路径链的距离小于等于1。
3.对于k个点如何check?每次check完点u和点v到LCA的距离后,把到LCA距离最远的那个点作为分支链去和下一个要查询的结点进行对比,这样贪心下去一定是最优的。
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn = 2e5+500; 4 const int maxbit = 18; 5 vector<int> g[maxn]; 6 int dep[maxn]; 7 int fa[maxn][maxbit]; 8 int Log[maxn]; 9 int n; 10 typedef long long ll; 11 void add(int u,int v){ 12 g[u].push_back(v),g[v].push_back(u); 13 } 14 void pre(){ 15 Log[0] = -1; 16 Log[1] = 0,Log[2] = 1; 17 for(int i = 3;i<maxn;i++) Log[i] = Log[i/2] + 1; 18 } 19 void dfs(int cur,int father){ 20 dep[cur] = dep[father] + 1; 21 fa[cur][0] = father; 22 for(int j = 1;(1<<j)<=n;j++){ 23 fa[cur][j] = fa[fa[cur][j-1]][j-1]; 24 } 25 for(int i = 0;i<g[cur].size();i++){ 26 if(g[cur][i]!=father){ 27 dfs(g[cur][i],cur); 28 } 29 } 30 } 31 int LCA(int u,int v){ 32 if(dep[u]<dep[v]) swap(u,v); 33 int dist = dep[u] - dep[v]; 34 while(dep[u]!=dep[v]){ 35 u = fa[u][Log[dep[u]-dep[v]]]; 36 } 37 if(u == v) return u; 38 for(int i = Log[dep[u]];i>=0;i--){ 39 if(fa[u][i]!=fa[v][i]){ 40 u = fa[u][i]; 41 v = fa[v][i]; 42 } 43 } 44 return fa[u][0]; 45 } 46 int main(){ 47 int q; 48 scanf("%d%d",&n,&q); 49 for(int i = 1;i<n;i++){ 50 int u,v; 51 scanf("%d%d",&u,&v); 52 add(u,v); 53 } 54 pre(); 55 dfs(1,0); 56 while(q--){ 57 int k;scanf("%d",&k); 58 bool f = 0; 59 int t[k+1] ; 60 for(int i = 1;i<=k;i++) scanf("%d",&t[i]); 61 int v = t[1];//当前对比点设为v 62 for(int i = 2;i<=k;i++){ 63 int lca = LCA(v,t[i]); 64 if(abs(dep[t[i]]-dep[lca]) > 1&& abs(dep[v]-dep[lca])>1){ 65 f = 1;//如果出现到lca距离同时大于1,则一定无法找到树链满足题意 66 break; 67 } 68 abs(dep[t[i]]-dep[lca])>abs(dep[v]-dep[lca])? v = t[i]:v = v; //如果t[i]到lca的距离更远,则把v更新为t[i],贪心地与下一个点对比。 69 } 70 if(!f) cout<<"YES"<<endl; 71 else cout<<"NO"<<endl; 72 } 73 return 0; 74 } 75 /* 76 8 77 13 13 9 12 13 1 13 1 78 */
Codeforces Round #629 (Div. 3) E. Tree Queries(LCA)
标签:break return contest 更新 处理 log 查询 namespace wap
原文地址:https://www.cnblogs.com/AaronChang/p/12590348.html