您的位置:首页 > 编程语言 > Java开发

HDU 3887 Counting Offspring(dfs序+树状数组)

2016-03-31 15:41 561 查看
题目链接

题意:给你一颗有n个节点的n-1边的树,以及树的根节点是p,问你是不是这个树,每个节点子节点中比这个节点的号码小的个数。

trick:注意根节点是题目给出的,所以加边的时候反方向边也是要加入的,接着就是dfs序的时候是要注意,由于反向边的存在,那么我们就要判断下。

#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define cl(a,b) memset(a,b,sizeof(a))
const int maxn=200005;
const  LL inf=1LL<<32;
double pi=acos(-1.0);
#define gcd __gcd
#define LCM(a,b) (a)*(b)/gcd(a,b)
#define X first
#define Y second
#define pb push_back
#define lowbit(s) (s&(-s))

struct Edge{
int to,next;
}edge[maxn];
int head[maxn],tot;
void addEdge(int u,int v){
edge[tot].to=v;
edge[tot].next=head[u];
head[u]=tot++;
}
int n,p;
int st[maxn];
int ed[maxn];
int c[maxn];
int cnt;
void dfs(int u,int fa){
st[u]=++cnt;
for(int i=head[u];~i;i=edge[i].next){
if(edge[i].to==fa)continue;
dfs(edge[i].to,u);
}
ed[u]=cnt;
}
void update(int x,int val){
for(int i=x;i<=n;i+=lowbit(i))c[i]+=val;
}
int sum(int x){
int ret=0;
for(int i=x;i;i-=lowbit(i))ret+=c[i];
return ret;
}
void init(){
cl(c,0);
cl(st,0);
cl(ed,0);
cl(head,-1);
tot=cnt=0;
}

int main(){
while(~scanf("%d%d",&n,&p)){
if(n==0&&p==0)return 0;
init();
for(int i=1;i<n;i++){
int x,y;
scanf("%d%d",&x,&y);
addEdge(x,y);
addEdge(y,x);
}
dfs(p,p);
for(int i=1;i<=n;i++){
update(st[i],1);
printf("%d%c",sum(ed[i])-sum(st[i]-1)-1,i==n?'\n':' ');
}

}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: