• 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
  • 相关阅读:
    记录一下自己的洛谷的题解
    初学java 学生管理系统——v0002版本
    初学java 学生管理系统——v0001版本
    Redis守护进程作用+数据类型
    java实现发送短信验证码
    Kali入侵入门版笔记!!!
    2020实现ssh公网外联和外网远程穿透以及内网穿透防火墙
    监控键盘和鼠标记录内容和截屏,更新版本2.0,增加了Linux服务端!!!
    Git管理软件开发项目入门版
    2020年Windows下开机自动执行最强
  • 原文地址:https://www.cnblogs.com/AaronChang/p/12357806.html
Copyright © 2020-2023  润新知