zoukankan      html  css  js  c++  java
  • bzoj 1924

    所用点的编号为输入顺序,因为只有在存在联通门的宫室中存在宝藏。其余点不考虑
    对于每一行,选定一个横天门,向该行横天门连双向边,其余门单向边
    纵列同理
    自.由门用map判周围八个点是否存在,存在即连边
    Tarjan缩点后DAG上dp求最长路

    bzoj 可过,luogu卡空间

    #include <bits/stdc++.h>
    
    #define gc getchar()
    
    inline int read() {
        int x = 0;
        char c = gc;
        while(c < '0' || c > '9') c = gc;
        while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = gc;
        return x;
    }
    
    const int N = 1e5 + 4, M = 1e6 + 4;
    const int xd[] = {0, -1, -1, -1, 0, 1, 1, 1};
    const int yd[] = {-1, -1, 0, 1, 1, 1, 0, -1};
    
    int head[N], head_2[N], cnt;
    struct Node {
        int u, v, nxt;
    };
    Node G[M], E[M];
    
    std:: vector <int> Vecx[M], Vecy[M];
    std:: map <int, int> Map[M];
    int X[N], Y[N], Opt[N];
    int Q, n, m;
    int Low[N], Dfn[N], Stack[N], Belong[N], Size[N], Scc, Tim, topp;
    bool vis[N];
    
    inline void Add_1(int u, int v) {
        if(u == v) return ;
        G[++ cnt].v = v;
        G[cnt].nxt = head[u];
        head[u] = cnt;
    }
    inline void Add_2(int u, int v) {
        E[++ cnt].v = v;
        E[cnt].nxt = head_2[u];
        head_2[u] = cnt;
    }
    
    inline void Build() {
        memset(head, -1, sizeof head);
        for(int i = 1; i <= n; i ++) {
            int x = 0, s = Vecx[i].size();
            for(int j = 0; j < s; j ++) {
                if(Opt[Vecx[i][j]] == 1) {
                    x = Vecx[i][j]; break;
                }
            }
            for(int j = 0; j < s; j ++) {
                Add_1(x, Vecx[i][j]);
                if(Opt[Vecx[i][j]] == 1) Add_1(Vecx[i][j], x);
            }
        }
        for(int i = 1; i <= m; i ++) {
            int y = 0, s = Vecy[i].size();
            for(int j = 0; j < s; j ++) {
                if(Opt[Vecy[i][j]] == 2) {
                    y = Vecy[i][j]; break;
                }
            }
            for(int j = 0; j < s; j ++) {
                Add_1(y, Vecy[i][j]);
                if(Opt[Vecy[i][j]] == 2) Add_1(Vecy[i][j], y);
            }
        }
        for(int i = 1; i <= Q; i ++) {
            if(Opt[i] == 3) {
                for(int j = 0; j < 8; j ++) {
                    int t = Map[X[i] + xd[j]][Y[i] + yd[j]];
                    if(t) Add_1(i, t);
                }
    
            }
        }
    }
    
    void Tarjan(int x) {
        Low[x] = Dfn[x] = ++ Tim;
        Stack[++ topp] = x;
        vis[x] = 1;
        for(int i = head[x]; ~ i; i = G[i].nxt) {
            int v = G[i].v;
            if(!Dfn[v]) {
                Tarjan(v);
                Low[x] = std:: min(Low[x], Low[v]);
            } else if(vis[v]) Low[x] = std:: min(Low[x], Low[v]);
        }
        if(Dfn[x] == Low[x]) {
            vis[x] = 0, Belong[x] = ++ Scc;
            Size[Scc] = 1;
            while(Stack[topp] != x) {
                vis[Stack[topp]] = 0, Belong[Stack[topp]] = Scc;
                topp --;
                Size[Scc] ++;
            }
            topp --;
        }
    }
    
    inline void Rebuild() {
        cnt = 0;
        memset(head_2, -1, sizeof head_2);
        for(int u = 1; u <= Q; u ++)
            for(int i = head[u]; ~ i; i = G[i].nxt)
                if(Belong[u] != Belong[G[i].v]) Add_2(Belong[u], Belong[G[i].v]);
    }
    
    int Answer, tot[N];
    
    void Dfs(int u) {
        vis[u] = 1;
        for(int i = head_2[u]; ~ i; i = E[i].nxt) {
            int v = E[i].v;
            if(!vis[v]) Dfs(v);
            tot[u] = std:: max(tot[u], tot[v]);
        }
        tot[u] += Size[u];
        Answer = std:: max(Answer, tot[u]);
    }
    
    int main() {
        Q = read(), n = read(), m = read();
        for(int i = 1; i <= Q; i ++) {
            X[i] = read(), Y[i] = read(), Opt[i] = read();
            Vecx[X[i]].push_back(i);
            Vecy[Y[i]].push_back(i);
            Map[X[i]][Y[i]] = i;
        }
        Build();
        for(int i = 1; i <= Q; i ++) if(!Dfn[i]) Tarjan(i);
        Rebuild();
        memset(vis, 0, sizeof vis);
        for(int i = 1; i <= Scc; i ++) if(!vis[i]) Dfs(i);
        std:: cout << Answer;
        return 0;
    }
  • 相关阅读:
    jQuery笔记(1)
    [bzoj 1878][SDOI2009]HH的项链
    [bzoj 1968][Ahoi2005]COMMON 约数研究
    [bzoj 1899][ZJOI2004]lunch 午餐
    [bzoj 1090][SCOI2003]字符串折叠
    CodeForces 1029E div3
    [bzoj 1270][BeijingWc2008]雷涛的小猫
    [bzoj 1260][CQOI 2007]涂色paint
    [AtCoder ARC101D/ABC107D] Median of Medians
    [luogu 1070]道路游戏(NOIP2009T4)
  • 原文地址:https://www.cnblogs.com/shandongs1/p/9461203.html
Copyright © 2011-2022 走看看