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 }