zoukankan      html  css  js  c++  java
  • [洛谷P4320]道路相遇

    题目大意:基本同上一题[bzoj5329][Sdoi2018]战略游戏,只是每个点集内只有两个点,且只有一组询问而已。(双倍经验?我反正就直接改了一下代码就交了)

    题解:同上一题(链接见“题目大意”)

    卡点:

    C++ Code:

    #include <cstdio>
    #include <cstring>
    #define maxn 1000010
    #define maxm 1000010
    int Tim, n, m, LCA;
    inline int min(int a, int b) {return a < b ? a : b;}
    inline void swap(int &a, int &b) {a ^= b ^= a ^= b;}
    struct Tree {
        #define root 1
        #define fa(u) dad[u][0]
        #define M 18
        int head[maxn], cnt;
        struct Edge {
            int to, nxt;
        } e[maxm << 1];
        inline void addE(int a, int b) {e[++cnt] = (Edge) {b, head[a]}; head[a] = cnt;}
        inline void add(int a, int b) {
            addE(a, b);
            addE(b, a);
        }
        
        int dad[maxn][M], dep[maxn], sz[maxn];
        int dfn[maxn], idx;
        void dfs(int u = root) {
            dfn[u] = ++idx;
            for (int i = 1; i < M; i++) dad[u][i] = dad[dad[u][i - 1]][i - 1];
            for (int i = head[u]; i; i = e[i].nxt) {
                int v = e[i].to;
                if (v != fa(u)) {
                    sz[v] = sz[u] + int(v <= n);
    //				printf("link %d %d
    ", v, sz[v]);
                    dep[v] = dep[u] + 1;
                    fa(v) = u;
                    dfs(v);
                }
            }
        }
        inline int LCA(int x, int y) {
            if (dep[x] < dep[y]) swap(x, y);
            for (int i = dep[x] - dep[y]; i; i &= i - 1) x = dad[x][__builtin_ctz(i)];
            if (x == y) return x;
            for (int i = M - 1; ~i; i--) if (dad[x][i] != dad[y][i]) x = dad[x][i], y = dad[y][i];
            return fa(x);
        }
        
        inline int len(int x, int y) {
            return sz[x] + sz[y] - (sz[::LCA = LCA(x, y)] << 1);
        }
        
        inline void init() {
            memset(head, 0, sizeof head); cnt = 0;
            memset(dfn, 0, sizeof dfn); idx = 0;
            sz[root] = 0;
        }
        #undef root
        #undef fa
        #undef M
    } T;
    
    struct Graph {
        #define root 1
        int head[maxn], cnt;
        struct Edge {
            int to, nxt;
        } e[maxm << 1];
        inline void addE(int a, int b) {e[++cnt] = (Edge) {b, head[a]}; head[a] = cnt;}
        inline void add(int a, int b) {
            addE(a, b);
            addE(b, a);
        }
        
        int DFN[maxn], low[maxn], idx, CNT;
        int S[maxn], top, tmp;
        void tarjan(int u = root) {
            DFN[u] = low[u] = ++idx;
            S[++top] = u;
            for (int i = head[u]; i; i = e[i].nxt) {
                int v = e[i].to;
                if (!DFN[v]) {
                    tarjan(v);
                    low[u] = min(low[u], low[v]);
                    if (low[v] >= DFN[u]) {
                        CNT++;
                        T.add(CNT, u);
                        do {
                            T.add(CNT, tmp = S[top--]);
                        } while (tmp != v);
                    }
                } else low[u] = min(low[u], DFN[v]);
            }
        }
        
        inline void init(int n) {
            memset(head, 0, sizeof head); cnt = 0;
            memset(DFN, 0, sizeof DFN); idx = 0;
            CNT = n;
        }
        #undef root
    } G;
    
    
    #define OnlineJudge
    #define read() R::READ()
    #include <cctype>
    namespace R {
        int x;
        #ifdef Online_Judge
        char *ch, op[1 << 26];
        inline void init() {
            fread(ch = op, 1, 1 << 26, stdin);
        }
        inline int READ() {
            while (isspace(*ch)) ch++;
            for (x = *ch & 15, ch++; isdigit(*ch); ch++) x = x * 10 + (*ch & 15);
            return x;
        }
        #else
        char ch;
        inline int READ() {
            ch = getchar();
            while (isspace(ch)) ch = getchar();
            for (x = ch & 15, ch = getchar(); isdigit(ch); ch = getchar()) x = x * 10 + (ch & 15);
            return x;
        }
        #endif
    }
    
    int main() {
        #ifdef Online_Judge
        R::init();
        #endif
        G.init(n = read()), T.init();
        for (int i = m = read(); i; i--) G.add(read(), read());
        G.tarjan();
        T.dfs();
        int Q = read();
        while (Q --> 0) printf("%d
    ", T.len(read(), read()) + int(LCA <= n));
        return 0;
    }
    
  • 相关阅读:
    Best Time to Buy and Sell Stock
    Remove Nth Node From End of List
    Unique Paths
    Swap Nodes in Pairs
    Convert Sorted Array to Binary Search Tree
    Populating Next Right Pointers in Each Node
    Maximum Subarray
    Climbing Stairs
    Unique Binary Search Trees
    Remove Duplicates from Sorted Array
  • 原文地址:https://www.cnblogs.com/Memory-of-winter/p/9651410.html
Copyright © 2011-2022 走看看