记录编号 158123 评测结果 AAAAAAAAAA
题目名称 [ZJOI 2012] 灾难 最终得分 100
用户昵称 Gravatar水中音 是否通过 通过
代码语言 C++ 运行时间 0.185 s
提交时间 2015-04-12 17:59:21 内存使用 8.87 MiB
显示代码纯文本
#include<iostream>
#include<cstdio>
using namespace std;
#define N 66000
#define pos 17
int n,m,i,p,j,zj1,zj2,zj3,ans[N],L,R;
int to[N<<2],ne[N<<2],head[N],rehead[N],sj=1;
int dep[N],f[N][pos],ins[N],A[N];
inline void addedge(int u,int v)
{
	ins[v]++;to[++sj]=v,ne[sj]=head[u],head[u]=sj;
	to[++sj]=u,ne[sj]=rehead[v],rehead[v]=sj;
}
int TO[N],NE[N],HEAD[N],SJ;
inline void ADDEDGE(int u,int v)
{TO[++SJ]=v,NE[SJ]=HEAD[u],HEAD[u]=SJ;}

inline int lca(int u,int v)
{
 	if(dep[u]>dep[v])zj2=u,u=v,v=zj2;
 	if(dep[u]!=dep[v])
 	{
 		zj2=dep[v]-dep[u];
 		for(j=0;j<pos;j++)if(zj2&(1<<j))
 		v=f[v][j];
 	}
 	if(v!=u)
 	{
 		for(j=pos-1;j>=0;j--)
 		if(f[u][j]!=f[v][j])
 		u=f[u][j],v=f[v][j];
 		u=f[u][0];
 	}
 	return u;
}

void init()
{
	scanf("%d",&n);
	for(i=1;i<=n;i++)
	{
		scanf("%d",&zj1);
		while(zj1)
		{
			addedge(zj1,i);
			scanf("%d",&zj1);
		}
		if(!ins[i])A[++R]=i;
	}
}
inline void DFS(int x)
{
	for(int h=HEAD[x];h;h=NE[h])
	if(TO[h]!=f[x][0])
	{
		DFS(TO[h]);
		ans[x]+=ans[TO[h]];
	}
	ans[x]++;
}
void work()
{
	while(L<R)
	{
		for(i=head[A[++L]];i;i=ne[i])
		if(!(--ins[to[i]]))A[++R]=to[i];
	}
	for(i=1;i<=n;i++)
	{
		if(rehead[A[i]])
			for(p=rehead[A[i]],zj1=to[p];p;p=ne[p])
			zj1=lca(zj1,to[p]);
		else zj1=n+1;
		
		ADDEDGE(zj1,A[i]);
		dep[A[i]]=dep[zj1]+1;
		f[A[i]][0]=zj1;
		for(p=1;p<pos;p++)f[A[i]][p]=f[f[A[i]][p-1]][p-1];
	}
	DFS(n+1);
}
int main()
{
	freopen("catas.in","r",stdin);
	freopen("catas.out","w",stdout);
	init();
	work();
	for(i=1;i<=n;i++)printf("%d\n",ans[i]-1);
	return 0;
}