• Codeforces 1304E. 1-Trees and Queries


    简述题意,给你一课最小支撑树,对每个询问,在原有的路径上增加x-y,问a-b是否有路径长度为k的路,每条路每个点可以重复使用

    由于是最小支撑树,我们可以用LCA来快速判断每个点之间的距离,那么现在就要判断情况,假设从原有的路上,a-b的距离为d,d=k时显然成立,当d<k时,若(d-k)%2=0也成立,因为若其是2的倍数,他可以轮流进入b与b的前驱,最后停在b上,那么我们如何判断新加的边的,距离的判定和前者一样,但是距离的大小变化了,设(x,y)表示x到y的最短路径,则从a到b就有三种情况

    1.(a,b) 该情况已经讨论过

    2.(a,x)+(b,y)+1,意思从a到x,x到y的路径长度为1,y再到b

    3.(a,y)+(b,x)+1,同理

    三种情况下的距离判断都一样,具体上代码看一下就懂了

    #include<bits/stdc++.h>
    using namespace std;
    #define lowbit(x) ((x)&(-x))
    typedef long long LL;
    
    const int maxm = 1e5+5;
    struct Node {
        int v, nex;
    } edges[maxm<<1];
    
    int head[maxm<<1], edgecnt, grand[maxm][21], depth[maxm], limit;
    
    void addedge(int u, int v) {
        edges[++edgecnt] = {v, head[u]};
        head[u] = edgecnt;
    }
    
    void dfs(int u, int fa) {
        depth[u] = depth[fa] + 1;
        grand[u][0] = fa;
        for(int i = 1; i <= limit; ++i) grand[u][i] = grand[grand[u][i-1]][i-1];
        for(int i = head[u]; i; i = edges[i].nex) {
            int v = edges[i].v;
            if(v != fa) dfs(v, u);
        }
    }
    
    int lca(int a, int b) {
        if(a == b) return a;
        if(depth[a] > depth[b]) swap(a, b);
        for(int i = limit; i >= 0; i--) 
            if(depth[a] <= depth[b] - (1<<i)) b = grand[b][i];
        if(a == b) return a;
        for(int i = limit; i >= 0; --i) {
            if(grand[a][i] == grand[b][i])
                continue;
            else {
                a = grand[a][i], b = grand[b][i];
            }
        }
        return grand[a][0];
    }
    
    int getdist(int a, int b) {
        int c = lca(a, b);
        return depth[a] + depth[b] - 2*depth[c];
    }
    
    
    void run_case() {
        int n; cin >> n;
        limit = floor(log(n+0.0) / log(2.0)) + 1;
        int u, v;
        for(int i = 0; i < n-1; ++i) {
            cin >> u >> v;
            addedge(u, v), addedge(v, u);
        }
        dfs(1, 0);
        int q; cin >> q;
        int a, b, x, y, k;
        while(q--) {
            cin >> x >> y >> a >> b >> k;
            int dist = getdist(a, b);
            bool flag = false;
            if(dist <= k && (k-dist)%2==0) flag = true;
            dist = getdist(a, x) + getdist(b, y) + 1;
            if(dist <= k && (k-dist)%2==0) flag = true;
            dist = getdist(a, y) + getdist(b, x) + 1;
            if(dist <= k && (k-dist)%2==0) flag = true;
            if(flag) cout << "YES
    ";
            else cout << "NO
    ";
        }
    }
     
    int main() {
        ios::sync_with_stdio(false), cin.tie(0);
        //cout.setf(ios_base::showpoint);cout.precision(10);
        //int t; cin >> t;
        //while(t--)
        run_case();
        cout.flush();
        return 0;
    }
    View Code
  • 相关阅读:
    基于RSA securID的Radius二次验证java实现(PAP验证方式)
    一些指令 & 一些知识 (Linux Spring log4j...)
    RSA, ACS5.X 集成配置
    Python中的动态属性与描述符
    设计模式(一):单例模式
    JavaWeb
    动态规划_背包问题
    动态规划_最长上升子序列
    MySQL复习
    动态规划_数字三角形
  • 原文地址:https://www.cnblogs.com/GRedComeT/p/12316678.html
Copyright © 2020-2023  润新知