zoukankan      html  css  js  c++  java
  • Codeforces 1304E 1-Trees and Queries (树上距离+思维)(翻译向)

    题意

    给你一棵树,q个询问(x,y,a,b,k),每次问你如果在(x,y)加一条边,那么a到b能不能走k步,同一个点可以走多次

    思路(翻译题解)

    对于一条a到b的最短路径x,可以通过左右横跳的方法把他扩大成任意的(x+2i(igeq 0)),只要存在一个能使得它等于k的i即可。。
    在这一题中,如果x和i连了边,那么就会存在三条可能的最短路径:(从哪到哪都是在原树上)
    1.从a到b
    2.从a到x,走加的边到y,从y到b
    3.从a到y,走加的边到x,从x到b
    判断是否存在满足就好了

    代码

    思路要整理一下树上问题的结构体了。。

    int n;
    int pre[maxn];
    vector<int>g[maxn];
    void dfs(int x, int fa, int dp){
        pre[x]=dp;
        for(int i = 0; i <(int)g[x].size(); i++){
            int y = g[x][i];
            if(y==fa)continue;
            dfs(y,x,dp+1);
        }
    }
    int dep[maxn],fa[maxn][34];
    int lg[maxn];
    void ddfs(int x, int lst){
        dep[x] = dep[lst] + 1;
        fa[x][0] = lst;
        for(int i = 1; (1<<i) <= dep[x]; i++){
            fa[x][i] = fa[fa[x][i-1]][i-1];
        }
        for(int i = 0; i < (int)g[x].size(); i++){
            int y = g[x][i];
            if(y==lst) continue;
            ddfs(y, x);
        }
        return;
    }
    int lca(int x, int y){
        if(dep[x] > dep[y])swap(x,y);
        while(dep[x] != dep[y]){
            if(lg[dep[y]-dep[x]]-1>=0)y = fa[y][lg[dep[y]-dep[x]]-1];
            else y = fa[y][0];
        }
        if(x==y) return x;
        for(int i = lg[dep[y]]; i >= 0; i--){
            if(fa[x][i] != fa[y][i]){
                x = fa[x][i];
                y = fa[y][i];
            }
        }
        return fa[x][0];
    }
    int len(int x ,int y){
        return pre[x]+pre[y]-2*pre[lca(x,y)];
    }
    int f(int x, int a, int b){
        int L =lca(a,b);
        if(lca(L,x)==L){
            return min(len(x,lca(x,a)),len(x,lca(x,b)));
        }
        else return len(x,L);
    }
    int main(){
        
        scanf("%d", &n);
        for(int i = 1; i <= n; i++){
            lg[i] = lg[i-1]+(1<<lg[i-1]==i);
        }
        for(int i = 1; i < n; i++){
            int x,y;
            scanf("%d %d" ,&x, &y);
            g[x].pb(y);g[y].pb(x);
        }
        dfs(1,0,0);
        ddfs(1,0);
        int q;
        scanf("%d", &q);
        while(q--){
            int x,y,a,b,k;
            int ok=0;
            scanf("%d %d %d %d %d", &x, &y, &a, &b, &k);
            if((len(a,x)+len(y,b)+1)%2==k%2&&(len(a,x)+len(y,b)+1)<=k)ok=1;
            if((len(a,y)+len(x,b)+1)%2==k%2&&(len(a,y)+len(x,b)+1)<=k)ok=1;
            if(len(a,b)%2==k%2&&len(a,b)<=k)ok=1;
            if(ok){
                printf("YES
    ");
            }
            else printf("NO
    ");
        }
        return 0;
    }
    
  • 相关阅读:
    残奥会女坐式排球决赛
    Visual C++ 调试器伪变量
    Project Chameleon Work In Progress 3
    pku1496 Word Index
    pku1083 Moving Tables
    pku3273 Monthly Expense
    pku1189 钉子和小球
    pku1018 Communication System
    关于tomcat报Error listenerStart和Context [*] startup failed due to previous errors两个错误的总结 东师理想
    java客户端提交数据到memcached方法memcached+java+client个人总结 东师理想
  • 原文地址:https://www.cnblogs.com/wrjlinkkkkkk/p/12316804.html
Copyright © 2011-2022 走看看