zoukankan      html  css  js  c++  java
  • JZOI5257. 小X的佛光

    洛谷AC通道!

    题目花里胡哨扯一堆,其实就是让我们求两条路径的重合点数。

    那么,直接求LCA然后计算即可。  

    对于路径 AC, CB, 其重叠路径即为 $(dis[(a、b -> LCA(A, B)] + dis[b、c -> LCA(B, C)] - dis[a、c -> LCA(A, C)]) / 2 + 1$  -> 除以$2$是因为重复计算了路径。加$1$是因为末端点B也算

    #include <bits/stdc++.h>
    using namespace std;
    #define N 1000010
    
    inline int read(){
        int x = 0, s = 1;
        char c = getchar();
        while(!isdigit(c)){
            if(c == '-')s = -1;
            c = getchar();
        }
        while(isdigit(c)){
            x = x * 10 + (c ^ '0');
            c = getchar();
        }
        return x * s;
    }
    
    struct node{
        int v, next;
    } t[N << 1];
    int f[N];
    
    int bian = 0;
    inline void add(int u, int v){
        t[++bian] = (node){v, f[u]}, f[u] = bian;
        t[++bian] = (node){u, f[v]}, f[v] = bian;
        return ;
    }
    
    int deth[N], siz[N], son[N], fa[N], top[N]; 
    
    #define v t[i].v
    void dfs1(int now, int father){
        siz[now] = 1;
        fa[now] = father;
        deth[now] = deth[father] + 1;
        for(int i = f[now]; i; i = t[i].next){
            if(v != father){
                dfs1(v, now);
                siz[now] += siz[v];
                if(siz[v] > siz[son[now]])
                    son[now] = v;
            }
        }
        return ;
    }
    
    void dfs2(int now, int tp){
        top[now] = tp;
        if(!son[now]) return ;
        dfs2(son[now], tp);
        for(int i = f[now]; i; i = t[i].next){
            if(v != fa[now] && v != son[now])
                dfs2(v, v);
        }
        return ;
    }
    
    int lca(int x, int y){
        while(top[x] != top[y]){
            if(deth[top[x]] < deth[top[y]]) swap(x, y);
            x = fa[top[x]];
        }
        return deth[x] > deth[y] ? y : x;
    } 
    
    
    #undef v
    
    int main(){
    //    freopen("hh.txt", "r", stdin);
    //    freopen("5.txt", "w", stdout);
        int n = read(), T = read(), num = read();
        for(int i = 1;i < n; i++){
            int x = read(), y = read();
            add(x, y);
        }
        if(num != 17 && num != 18){
            dfs1(1, 1);
            dfs2(1, 1);
            while(T--){
                int a = read(), b = read(), c = read();
                int ans1 = abs(2 * deth[lca(a, b)] - deth[b] - deth[a]);
                int ans2 = abs(2 * deth[lca(a, c)] - deth[a] - deth[c]);
                int ans3 = abs(2 * deth[lca(b, c)] - deth[b] - deth[c]);
                printf("%d
    ", (ans1  + ans3 - ans2) / 2 + 1);
            }
        }
    
        else {
            while(T--){
                int a = read(), b = read(), c = read();
                if((a < b && c > b) || (c < b && a > b)) puts("1");
                else {
                    printf("%d
    ", min(abs(b - a), abs(c - b)) + 1) ;
                }
            } 
        }
        
        return 0;
    }
  • 相关阅读:
    codeforces C. Fixing Typos 解题报告
    codeforces B. The Fibonacci Segment 解题报告
    codeforces B. Color the Fence 解题报告
    codeforces B. Petya and Staircases 解题报告
    codeforces A. Sereja and Bottles 解题报告
    codeforces B. Levko and Permutation 解题报告
    codeforces B.Fence 解题报告
    tmp
    API 设计 POSIX File API
    分布式跟踪的一个流行标准是OpenTracing API,该标准的一个流行实现是Jaeger项目。
  • 原文地址:https://www.cnblogs.com/wondering-world/p/13373765.html
Copyright © 2011-2022 走看看