Codeforces 1304E. 1-Trees and Queries 代码(LCA 树上两点距离判奇偶)

https://codeforces.com/contest/1304/problem/E

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 const int maxbit = 20;
 5 const int maxn = 1e5+5;
 6 vector<int> G[maxn];
 7 int depth[maxn];
 8 int fa[maxn][maxbit];
 9 int Log[maxn];
10 int N;
11 void pre(){
12     Log[0] = -1;
13     Log[1] = 0,Log[2] = 1;
14     for(int i = 3;i<maxn;i++) Log[i] = Log[i/2] + 1;
15 } 
16 void dfs(int cur,int father){//dfs预处理 
17     depth[cur] = depth[father] + 1;//当前结点的深度为父亲结点+1 
18     fa[cur][0] = father;//更新当前结点的父亲结点 
19     for(int j = 1;(1<<j)<=N;j++){//倍增更新当前结点的祖先 
20         fa[cur][j] = fa[fa[cur][j-1]][j-1];
21     }
22     for(int i = 0;i<G[cur].size() ;i++){
23         if(G[cur][i] != father) {//dfs遍历 
24             dfs(G[cur][i],cur);
25         }
26     }
27 }
28 int LCA(int u,int v){
29     if(depth[u]<depth[v]) swap(u,v);
30     int dist = depth[u] - depth[v];//深度差 
31     while(depth[u]!=depth[v]){//把较深的结点u倍增到与v高度相等 
32         u = fa[u][Log[depth[u]-depth[v]]];
33     }
34     if(u == v) return u;//如果u倍增到v,说明v是u的LCA 
35     for(int i = Log[depth[u]];i>=0;i--){//否则两者同时向上倍增 
36         if(fa[u][i]!=fa[v][i]){//如果向上倍增的祖先不同,说明是可以继续倍增 
37             u = fa[u][i];//替换两个结点 
38             v = fa[v][i];
39         }
40     }
41     return fa[u][0];//最终结果为u v向上一层就是LCA 
42 } 
43 int main()
44 {
45     pre();
46     cin>>N;
47     for(int i = 1;i<N;i++){
48         int u,v;
49         cin>>u>>v;
50         G[u].push_back(v),G[v].push_back(u);  
51     }
52     dfs(1,0);
53     int q;cin>>q;
54     while(q--){
55         int x,y,a,b,k;
56         cin>>x>>y>>a>>b>>k;
57         int t1 = LCA(a,b),t2 = LCA(a,x),t3 = LCA(a,y),t4 = LCA(b,x),t5  = LCA(b,y);
58         int dis = abs(depth[t1]-depth[a])+abs(depth[t1]-depth[b]);
59         if(dis%2 == k%2 && dis <=k ){
60 //            cout<<"De1"<<endl;
61             cout<<"YES"<<endl;
62             continue;
63         }
64         int dis1 = abs(depth[t2]-depth[a])+abs(depth[t2]-depth[x]);
65         int dis2 = abs(depth[t5]-depth[b])+abs(depth[t5]-depth[y]); 
66         if( (dis1+dis2+1)%2 == k%2  && dis1+dis2+1 <= k){
67 //            cout<<"de2"<<endl;
68             cout<<"YES"<<endl;
69             continue;
70         }
71         dis1 = abs(depth[t3]-depth[a])+abs(depth[t3]-depth[y]);
72         dis2 = abs(depth[t4]-depth[b])+abs(depth[t4]-depth[x]);
73         if((dis1+dis2+1)%2 == k%2 && dis1+dis2+1 <= k){
74 //            cout<<"de3"<<endl;
75             cout<<"YES"<<endl;
76             continue;
77         } 
78         cout<<"NO"<<endl;
79     }
80     return 0;
81 }
View Code
原文地址:https://www.cnblogs.com/AaronChang/p/12357806.html