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;
    }
    
  • 相关阅读:
    使用Kmeans进行聚类,用calinski_harabaz_score评价聚类效果
    使用Autoencoder进行降维
    MongoDB 之 MongoDB简介与安装 MongoDB 1
    我的淘宝客之路 起步
    Excel批量导入Orale
    CAB压缩包文件制作
    策略模式
    设计OA系统的用户角色权限分配
    java语言中的限定词
    jQuery LigerUI使用培训
  • 原文地址:https://www.cnblogs.com/Memory-of-winter/p/9651410.html
Copyright © 2011-2022 走看看