#include <iostream>
#include <cstring>
#include <cstdio>
#include <stack>
using namespace std;
const int N=100005;
int f[N],c[N<<1],s[N<<1],e[N<<1],next[N<<1],n,p,l[N],r[N];
bool vis[N];
void connect(int i,int u,int v){
next[i]=s[u];//同起点
s[u]=i;
e[i]=v;
}
int lowbit(int i){
return i&-i;
}
void update(int x,int y){
for(int i=x;i<=(N<<1);i+=lowbit(i) )
c[i]+=y;
}
int sum(int x){
int ret=0;
for(int i=x;i>0;i-=lowbit(i))
ret+=c[i];
return ret;
}
void dfs(int root){//非递归
int cnt=1;//初始化和下面的cnt++还有求f[i]的下标有关系
stack<int> ss;
ss.push(root);
while(!ss.empty()){
int top=ss.top();
if(!vis[top]){
vis[top]=true;//标记
l[top]=cnt++;//第一次访问
}
bool flag=false;
for(int i=s[top];i;i=next[i]){//枚举下一个节点
if(!vis[e[i]]){
flag=true;
ss.push(e[i]);
s[top]=next[i];//记录当前点遍历到了第几个邻接点了,返回的时候从这个邻接点开始
break;
}
}
if(flag)continue;
if(vis[top]){
ss.pop();
r[top]=cnt++;//第二次访问
}
}
}
/*
void dfs(int x,int pre){//爆栈
int tmp=sum(x-1);
for(int i=s[x];i;i=next[i])
if(e[i]!=pre){
update(e[i],1);
dfs(e[i],x);
}
f[x]=sum(x-1)-tmp;
//r[x]=cnt;
}
*/
int main()
{
int u,v;
while(scanf("%d%d",&n,&p)&&(n+p)){
memset(c,0,sizeof(c));
memset(next,0,sizeof(next));
memset(s,0,sizeof(s));
memset(f,0,sizeof(f));
memset(vis,0,sizeof(vis));
for(int i=1,j=1;i<n;i++){
scanf("%d%d",&u,&v);
connect(j++,u,v);
//connect(j++,v,u);不加的话,wa,,,有自反性,不知哪个为父节点
}
dfs(p);
for(int i=1;i<n;i++){
printf("%d ",sum(r[i]-1)-sum(l[i]));
update(l[i],1);
}
cout<<sum(r[n]-1)-sum(l[n])<<endl;
}
return 0;
}
hdu3887Counting Offspring
最新推荐文章于 2019-08-24 22:31:47 发布