zoukankan      html  css  js  c++  java
  • P2597 [ZJOI2012]灾难

    P2597 [ZJOI2012]灾难

    题目描述

    见链接


    Solution

    建立支配树即可


    Addition

    步骤:

    1. 反向建边
    2. 拓扑排序
    3. 按反拓扑序依次加入支配树节点

    加入节点时, 取其所有原图父亲的LCALCA作新树的父亲


    Attention

    两个字符1,01,0调了 6hours6-hours !!!
    要时刻注意循环边界 !!!


    Code

    #include<bits/stdc++.h>
    #define reg register
    
    const int maxn = 80000;
    
    int N, cnt, num0, Lim;
    int B[maxn], In[maxn];
    int F[maxn][18];
    int dep[maxn];
    int head[maxn];
    int size[maxn];
    
    struct Edge{ int nxt, to; } edge[maxn<<1];
    
    void Add(int from, int to){
            edge[++ num0] = (Edge){ head[from], to };
            head[from] = num0;
    }
    
    int LCA(int a, int b){
            if(dep[a] < dep[b]) std::swap(a, b);
            for(reg int i = 17; i >= 0; i --)
                    if(dep[F[a][i]] >= dep[b]) a = F[a][i];
            if(a == b) return a;
            for(reg int i = 17; i >= 0; i --)
                    if(F[a][i] != F[b][i]) a = F[a][i], b = F[b][i];
            return F[a][0];
    }
    
    void DFS(int k, int fa){
            size[k] = 1;
            for(reg int i = head[k]; i; i = edge[i].nxt){
                    if(i <= Lim) continue ;
                    int to = edge[i].to;
                    if(to == fa) continue ;
                    DFS(to, k);
                    size[k] += size[to];
            }
    }
    
    int main(){
            scanf("%d", &N);
            for(reg int i = 1; i <= N; i ++){
                    int x;
                    scanf("%d", &x);
                    while(x) Add(i, x), In[x] ++, scanf("%d", &x);
            }
            Lim = num0;
            std::queue <int> Q;
            for(reg int i = 1; i <= N; i ++) if(!In[i]) Q.push(i);
            while(!Q.empty()){
                    int ft = Q.front(); Q.pop();
                    B[++ cnt] = ft;
                    for(reg int i = head[ft]; i; i = edge[i].nxt){
                            int to = edge[i].to;
                            if(!(-- In[to])) Q.push(to); 
                    }
            }
            dep[N+1] = 1;
            for(reg int i = 0; i <= 17; i ++) F[N+1][i] = N+1;
            for(reg int i = cnt; i >= 1; i --){
                    int s = N+1, x = B[i];
                    if(head[x]){
                            s = edge[head[x]].to;
                            for(reg int j = head[x]; j; j = edge[j].nxt) 
                                    s = LCA(s, edge[j].to);
                    }
                    dep[x] = dep[s] + 1, F[x][0] = s;
                    Add(s, x);
                    for(reg int j = 1; j <= 17; j ++) F[x][j] = F[F[x][j-1]][j-1];
            }
            DFS(N+1, 0);
            for(reg int i = 1; i <= N; i ++) printf("%d
    ", size[i] - 1);
            return 0;
    }
    
    
  • 相关阅读:
    EBS SQL > Form & Report
    oracle sql 优化分析点
    MRP 物料需求计划
    MRPII 制造资源计划
    Barcode128 应用实务
    Oracle SQL语句优化技术分析
    APPSQLAP10710 Online accounting could not be created. AP Invoice 无法创建会计分录
    Oracle数据完整性和锁机制
    ORACLE Responsibility Menu Reference to Other User
    EBS 常用 SQL
  • 原文地址:https://www.cnblogs.com/zbr162/p/11822668.html
Copyright © 2011-2022 走看看