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;
    }
  • 相关阅读:
    数据分析师入门——用 Pandas 进行数据预处理:数据清洗与可视化
    hdu 1532 Dinic模板(小白书)
    二分图的最大匹配、完美匹配和匈牙利算法(转)
    HDU 1532 (Dinic算法)
    HDU 1532 Drainage Ditches EK算法 flod算法
    Edmonds_Karp 算法入门详解(转)
    UVa 10801
    Codeforces Round #359 (Div. 2)C
    Codeforces Round #358 (Div. 2)B. Alyona and Mex
    int long long范围
  • 原文地址:https://www.cnblogs.com/wondering-world/p/13373765.html
Copyright © 2011-2022 走看看