zoukankan      html  css  js  c++  java
  • LCA Codeforces 100685G Gadget Hackwrench

    题目传送门

    题意:一棵有向的树,问u到v是否可达

    分析:假设是无向树,DFS时正向的权值+1,反向的权值-1,然后找到LCA后判断dep数组和d数组就可以了

    /************************************************
    * Author        :Running_Time
    * Created Time  :2015/10/5 星期一 10:28:49
    * File Name     :G_2.cpp
     ************************************************/
    
    #include <cstdio>
    #include <algorithm>
    #include <iostream>
    #include <sstream>
    #include <cstring>
    #include <cmath>
    #include <string>
    #include <vector>
    #include <queue>
    #include <deque>
    #include <stack>
    #include <list>
    #include <map>
    #include <set>
    #include <bitset>
    #include <cstdlib>
    #include <ctime>
    using namespace std;
    
    #define lson l, mid, rt << 1
    #define rson mid + 1, r, rt << 1 | 1
    typedef long long ll;
    const int N = 1e5 + 10;
    const int INF = 0x3f3f3f3f;
    const int D = 20;
    const int MOD = 1e9 + 7;
    const double EPS = 1e-8;
    struct Edge {
        int v, d, nex;
    }edge[N<<1];
    int rt[D][N];
    int dep[N], d[N];
    int head[N], e;
    
    void init(void) {
        memset (head, -1, sizeof (head));
        e = 0;
    }
    
    void add_edge(int u, int v, int dir) {
        edge[e] = (Edge) {v, dir, head[u]};
        head[u] = e++;
    }
    
    void DFS(int u, int fa, int dis)  {
        dep[u] = dep[fa] + 1;
        d[u] = dis;
        for (int i=head[u]; ~i; i=edge[i].nex)  {
            int v = edge[i].v;
            if (v == fa)    continue;
            rt[0][v] = u;
            DFS (v, u, dis + edge[i].d);
        }
    }
    
    int LCA(int u, int v)  {
        if (dep[u] < dep[v])    {
            swap (u, v);
        }
        for (int i=0; i<D; ++i)  {
            if ((dep[u] - dep[v]) >> i & 1)    {
                u = rt[i][u];
            }
        }
        if (u == v) return u;
        for (int i=D-1; i>=0; --i)  {
            if (rt[i][u] != rt[i][v])   {
                u = rt[i][u];
                v = rt[i][v];
            }
        }
        return rt[0][v];
    }
    
    int main(void)    {
        int n;
        while (scanf ("%d", &n) == 1)   {
            init ();
            for (int u, v, i=1; i<n; ++i) {
                scanf ("%d%d", &u, &v);
                add_edge (u, v, 1);
                add_edge (v, u, -1);
            }
            DFS (1, 0, 0);
            for (int i=1; i<D; ++i) {
                for (int j=1; j<=n; ++j)    {
                    rt[i][j] = rt[i-1][rt[i-1][j]];
                }
            }
            int m;  scanf ("%d", &m);
            while (m--) {
                int u, v;   scanf ("%d%d", &u, &v);
                int f = LCA (u, v);
                if (dep[u] - dep[f] != d[f] - d[u]) puts ("No");
                else if (dep[v] - dep[f] != d[v] - d[f])    puts ("No");
                else    puts ("Yes");
            }
        }
    
        return 0;
    }
    

      

    编译人生,运行世界!
  • 相关阅读:
    【iCore、iCore2 双核心板】EPCS 实验(SPI Flash)(基于Verilog语言)
    【iCore2双核心板】SRAM 读写实验(基于Verilog语言)
    大便难案
    乌梅丸案二则
    奔豚
    中医对甲流的认识
    大青龙汤临床应用
    中风之补阳还五汤
    时方的魅力
    艾灸急治
  • 原文地址:https://www.cnblogs.com/Running-Time/p/4857388.html
Copyright © 2011-2022 走看看