[Luogu 3398] 仓鼠找sugar
[Luogu 3398] 仓鼠找sugar
又是 LCA…
前两天死活写不过的一个题今天终于顺手切了。
思路嘛参考了一楼题解。
就是说,对于 a, b, c, d 四个点,
令 x = LCA(a, b), y = LCA(c, d),
两条路径有交叉,当且仅当 c, d 至少一个在 x 的子树下,且 a, b 至少一个在 y 的子树下。
由于我是 HLD 求的 LCA,第一遍 DFS 时顺手把子树大小求了,后边判断在不在一棵子属下的时候就可以很方便了。
就这样。
#include <algorithm>
#include <cstdio>
const int MAXN = 100010; 
int n, q; 
struct Graph
{
    struct Edge
    {
        int to; 
        Edge *next; 
        Edge(int to, Edge* next): to(to), next(next) {}
        ~Edge(void)
        {
            if(next != NULL)
                delete next; 
        }
    }*head[MAXN]; 
    Graph(int n)
    {
        std :: fill(head + 1, head + n + 1, (Edge*)NULL); 
    }
    ~Graph(void)
    {
        for(int i = 1; i <= n; ++i)
            delete head[i]; 
    }
    void AddEdges(int u, int v)
    {
        head[u] = new Edge(v, head[u]); 
        head[v] = new Edge(u, head[v]); 
    }
}*G; 
namespace HLD
{
    int num; 
    struct Node
    {
        int depth, father, son, top, size, DFN; 
    }s[MAXN]; 
    void DFS1(int u, int k)
    {
        s[u].depth = k; 
        s[u].size = 1; 
        int v; 
        for(Graph :: Edge *i = G -> head[u]; i != NULL; i = i -> next)
            if(!s[v = i -> to].size)
            {
                DFS1(v, k + 1); 
                s[u].size += s[v].size; 
                s[v].father = u; 
                if(s[v].size > s[s[u].son].size)
                    s[u].son = v; 
            }
    }
    void DFS2(int u, int top)
    {
        s[u].top = top; 
        s[u].DFN = ++num; 
        if(s[u].son)
            DFS2(s[u].son, top); 
        int v; 
        for(Graph :: Edge *i = G -> head[u]; i != NULL; i = i -> next)
            if(!s[v = i -> to].DFN)
                DFS2(v, v); 
    }
    void Init(void)
    {
        DFS1(1, 1); 
        DFS2(1, 1); 
    }
    int LCA(int x, int y)
    {
        int a, b; 
        while((a = s[x].top) ^ (b = s[y].top))
            if(s[a].depth > s[b].depth)
                x = s[a].father; 
            else
                y = s[b].father; 
        return s[x].depth < s[y].depth ? x : y; 
    }
    bool Range(int x, int y)
    {
        return s[x].DFN <= s[y].DFN && s[y].DFN < s[x].DFN + s[x].size; 
    }
    bool Query(int a, int b, int c, int d)
    {
        int x = LCA(a, b), y = LCA(c, d); 
        return (Range(x, c) || Range(x, d)) && (Range(y, a) || Range(y, b)); 
    }
}
int main(void)
{
    scanf("%d %d", &n, &q); 
    G = new Graph(n); 
    for(int i = 1, u, v; i < n; ++i)
    {
        scanf("%d %d", &u, &v); 
        G -> AddEdges(u, v); 
    }
    HLD :: Init(); 
    for(int i = 1, a, b, c, d; i <= q; ++i)
    {
        scanf("%d %d %d %d", &a, &b, &c, &d); 
        puts(HLD :: Query(a, b, c, d) ? "Y" : "N"); 
    }
    return 0; 
}
谢谢阅读。

 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号