灾难、、、
这么恶心 4个小时
zjoi的时候也只有5个半小时啊
跪跪跪、、、、、、
哎 还是我太弱了、、、、、
topsort + lca
管他叫 ”灭绝树“
#include <cstring>
#include <cstdio>
#include <queue>
#define cle(a,b) memset(a,b,sizeof a)
using namespace std;
int n;
struct edge {
int v,next;
}e[10000000];
int cnt;
int head[65538];
int thead[65538];
int HEAD[65538];
int t,u,v;
int fa[65538][17],depth[65538];
int cause[65538];
int ts[65538],in[65538];
queue<int>q;
void adde (int u,int v) {
e[++cnt].v = v;
e[cnt].next = thead[u];
thead[u] = cnt;
e[++cnt].v = u;
e[cnt].next = head[v];
head[v] = cnt;
}
void read () {
cle(head,-1);
cle(thead,-1);
cle(HEAD,-1);
scanf("%d",&n);
for(int i = 1;i <= n;i++) {
while(scanf("%d",&t),t) {
adde(t,i);
in[i]++;
}
}
}
void topsort () {
t = 0;
for(int i = 1;i <= n;i++)
if(!in[i])
q.push(i);
while(!q.empty()) {
u = q.front();
q.pop();
ts[++t] = u;
for(int i = thead[u];i != -1;i = e[i].next) {
v = e[i].v;
in[v]--;
if(!in[v])
q.push(v);
}
}
}
void go_up (int &u,int d) {
int temp = 16;
while(d) {
if((1 << temp) <= d) {
d -= (1 << temp);
u = fa[u][temp];
}
temp--;
}
}
int lca (int u,int v) {
if(depth[u] != depth[v])
go_up(u,depth[u] - depth[v]);
if(u == v)
return u;
int temp = 17;
do {
if(fa[u][--temp] != fa[v][temp]) {
u = fa[u][temp];
v = fa[v][temp];
}
}while(temp);
return fa[v][0];
}
void ADDE (int u,int v) {
e[++cnt].v = v;
e[cnt].next = HEAD[u];
HEAD[u] = cnt;
}
void build () {
for(int i = 1;i <= n;i++) {
t = -1;
for(int j = head[ts[i]];j != -1;j = e[j].next) {
if(t == -1)
t = e[j].v;
else t = lca( depth[t] > depth[e[j].v] ? t : e[j].v , depth[t] > depth[e[j].v] ? e[j].v : t );
}
fa[ts[i]][0] = t == -1 ? 0 : t;
depth[ts[i]] = depth[t] + 1;
ADDE(t,ts[i]);
for(int j = 1;j <= 16;j++)
fa[ts[i]][j] = fa[fa[ts[i]][j - 1]][j - 1];
}
}
void dfs (int U) {
for(int i = HEAD[U];i != -1;i = e[i].next) {
dfs(e[i].v);
cause[U] += cause[e[i].v] + 1;
}
}
int main () {
read();
topsort();
build();
for(int i = 1;i <= n;i++)
if(depth[i] == 1)
dfs(i);
for(int i = 1;i <= n;i++)
printf("%d\n",cause[i]);
}