灭绝树
就是把拓扑图变成变成一棵树然后高度压缩一下,就变成了灭绝树
#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;
}