灭绝树

就是把拓扑图变成变成一棵树然后高度压缩一下,就变成了灭绝树

#include<bits/stdc++.h>
#define debug(x) cerr << #x <<" = " << x << endl
using namespace std;
const int N = 2e6 + 10;
const int Log = 20;
struct edge
{
    int to, nxt;
}e[N << 1];
int head[N], tot = 0;
int n, deg[N], siz[N];
vector<int> g[N];
int f[Log + 5][N];
int pa[N], dep[N];
void adde(int u, int v){ e[++tot] = edge{v, head[u]}, head[u] = tot, deg[v]++;}
void addg(int u, int v){g[u].push_back(v);}
int LCA(int u, int v)
{
    if(dep[u] < dep[v]) swap(u, v);
    for(int i = Log; i >= 0; i--)
    {
        if(dep[f[i][u]] >= dep[v]) 
        {
            u = f[i][u];
        }
    }
    if(u == v) return u;
    for(int i = Log; i >= 0; i--)
    {
        if(f[i][u] != f[i][v])
        {
            u = f[i][u];
            v = f[i][v];
        }
    }
    return f[0][u];
}
void upd(int u)
{
    f[0][u] = pa[u];
    dep[u] = dep[pa[u]] + 1;
    for(int i = 1; i <= Log; i++) f[i][u] = f[i - 1][f[i - 1][u]];
    return;
}
void topsort()
{
    for(int i = 2; i <= n; i++) if(!deg[i]) adde(1, i);
    dep[0] = -1;
    queue<int> q;
    for(int i = 1; i <= n; i++) if(!deg[i]) q.push(i);
    for(; !q.empty(); )
    {
        int u = q.front();
        q.pop();
        upd(u);
        for(int i = head[u]; i; i = e[i].nxt)
        {
            int v = e[i].to;
            if(pa[v] == 0) pa[v] = u;
            else pa[v] = LCA(pa[v], u);
            deg[v]--;
            if(!deg[v]) q.push(v);
        }
    }
    return;
}

void rebuild()
{
    for(int i = 2; i <= n; i++) addg(pa[i], i);
    return;
}

void dfs(int u)
{
    siz[u] = 1;
    for(int i = 0; i < (int)g[u].size(); i++)
    {
        int v = g[u][i];
        dfs(v);
        siz[u] += siz[v];
    }
    return;
}

int main()
{
    scanf("%d", &n);
    n++;
    for(int i = 2; i <= n; i++)
    {
        int to;
        while(scanf("%d", &to) && to) adde(to + 1, i);
    }    
    topsort();
    rebuild();
    dfs(1);
    for(int i = 2; i <= n; i++)  printf("%d\n", siz[i] - 1);
    return 0;
}
posted @ 2020-10-03 11:12  SegmentTree  阅读(16)  评论(0编辑  收藏  举报