其他分享
首页 > 其他分享> > P3398 仓鼠找sugar

P3398 仓鼠找sugar

作者:互联网

题目意思很清楚,求树上两条路径是否相交。

乱模拟就可以发现规律:当一条路径的lca在另外一条路径上的时候,这两条路径相交。

证明方法从题解的讨论里面看来的“浮尘ij”dalao摘过来:

可以反证,(不考虑两个lca相同的情况)两个lca到交点各有一条路径,他们到根节点又各有一条路径,出现环,矛盾。

又有一个问题:如何判断一个点在一个路径上面?

可以用到性质:该点到路径两端点的距离之和等于整条路径的长度。

用树剖写下lca真是大炮打蚊子233

代码:

#include<bits/stdc++.h>
using std::cin;
using std::cout;
using std::endl;
const int maxn = 100005;
int n, m;
struct Edges {
    int next, to;
} e[maxn << 1];
int head[maxn], tot;
// 
int size[maxn], wson[maxn], fa[maxn], dep[maxn];
int top[maxn];
int read() {
    int ans = 0;
    char ch = getchar();
    while(!isdigit(ch)) ch = getchar();
    while(isdigit(ch)) ans = ans * 10 + ch - '0', ch = getchar();
    return ans;
}
void link(int u, int v) {
    e[++tot] = (Edges){head[u], v};
    head[u] = tot;
}
void dfs1(int u, int f) {
    dep[u] = dep[f] + 1; fa[u] = f; size[u] = 1;
    for(int i = head[u]; i; i = e[i].next) {
        int v = e[i].to;
        if(v == f) continue;
        dfs1(v, u);
        size[u] += size[v];
        if(size[v] > size[wson[u]]) wson[u] = v;
    }
}
void dfs2(int u, int topf) {
    top[u] = topf;
    if(wson[u]) dfs2(wson[u], topf);
    for(int i = head[u]; i; i = e[i].next) {
        int v = e[i].to;
        if(v == fa[u] || v == wson[u]) continue;
        dfs2(v, v);
    }
}
int getlca(int u, int v) {
    while(top[u] != top[v]) {
        if(dep[top[u]] < dep[top[v]]) std::swap(u, v);
        u = fa[top[u]];
    }
    if(dep[u] > dep[v]) std::swap(u, v);
    return u;
}
int dist(int u, int v) {
    int lca = getlca(u, v);
    return dep[u] - dep[lca] + dep[v] - dep[lca];
}
int main() {
    n = read(), m = read();
    for(int i = 1; i < n; i++) {
        int u = read(), v = read();
        link(u, v); link(v, u);
    }
    dfs1(1, 0); dfs2(1, 1);
    while(m--) {
        int a = read(), b = read(), c = read(), d = read();
        int lca1 = getlca(a, b), lca2 = getlca(c, d);
        if(dep[c] > dep[d]) std::swap(c, d);
        if(dep[a] > dep[b]) std::swap(a, b);
        if(dist(c, lca1) + dist(lca1, d) == dist(c, d)) puts("Y");
        else if(dist(a, lca2) + dist(lca2, b) == dist(a, b)) puts("Y");
        else puts("N");
    }
    return 0;
}

标签:std,dist,int,sugar,dep,read,lca,P3398,仓鼠
来源: https://www.cnblogs.com/Garen-Wang/p/10959576.html