ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

CF1304E 1-Trees and Queries

2021-11-02 22:02:44  阅读:203  来源: 互联网

标签:int top tr Trees son CF1304E Queries check dis


题目链接

对树的路径进行操作,不难想到树的路径是唯一的,离不开LCA

添加一条新边后,答案有两种可能,一是走原树上路径,二是通过这条边走到

对于后者,其实答案就是dis(a,x)+1+dis(y,b)或者dis(a,y)+1+dis(x,b)

均是树上原有的,LCA可求

但是有个特殊情况,可以反复横跳(恶心心

但是反复横跳的奇偶性不变,只要有一个答案<=K并且和K奇偶性相同即可

#include <cstdio>
#include <iostream>
using namespace std;

#define MAXN 100005

struct edge {
    int v,next;
} G[MAXN<<1];
int head[MAXN],tot = 0;

inline void add(int u,int v) {
    G[++tot].v = v; G[tot].next = head[u]; head[u] = tot;
}

struct Tree {
    int son[MAXN],size[MAXN],fa[MAXN],d[MAXN];
    int top[MAXN];

    void dfs1(int u,int father) {
        fa[u] = father; d[u] = d[father] + 1;
        size[u] = 1; son[u] = 0;
        for(int i=head[u];i;i=G[i].next) {
            int v = G[i].v; if(v==fa[u]) continue;
            dfs1(v,u); size[u] += size[v];
            if(size[v]>size[son[u]]) son[u] = v; 
        }
    }

    void dfs2(int u,int tp) {
        top[u] = tp;
        if(son[u]) dfs2(son[u],tp);
        for(int i=head[u];i;i=G[i].next) {
            int v = G[i].v; if(v==fa[u]||v==son[u]) continue;
            dfs2(v,v);
        }
    }

    inline void init() {
        d[1] = size[0] = 0;
        dfs1(1,1); dfs2(1,1);
    }

    inline int LCA(int u,int v) {
        while(top[u]!=top[v]) {
            if(d[top[u]]<d[top[v]]) swap(u,v);
            u = fa[top[u]];
        }
        return d[u]>d[v]?v:u;
    }
    inline int dis(int u,int v) {
        int lca = LCA(u,v);
        return (d[u]-d[lca]) + (d[v]-d[lca]);
    }
} tr;

inline bool check(int dis1,int dis2) {
    return (dis1<=dis2&&(dis1&1)==(dis2&1));
}

int N,Q;

int main() {

    ios::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);

    cin >> N;
    for(int i=1;i<N;++i) {
        int u,v; cin >> u >> v;
        add(u,v); add(v,u);
    }

    tr.init();

    cin >> Q;
    for(int i=1;i<=Q;++i) {
        int x,y,a,b,k; cin >> x >> y >> a >> b >> k;
        if(check(tr.dis(a,b),k)||check(tr.dis(a,x)+1+tr.dis(y,b),k)||check(tr.dis(a,y)+1+tr.dis(x,b),k)) cout << "YES\n";
        else cout << "NO\n";
    }

    return 0;
}

标签:int,top,tr,Trees,son,CF1304E,Queries,check,dis
来源: https://www.cnblogs.com/Neworld1111/p/15501433.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有