1131: [POI2008]Sta
stupid_lulu
posted @ 2013年3月19日 15:26
in poi
, 968 阅读
裸的treedp。。两遍dfs,第一遍求出g[i]表示以i为根的子树的深度和,第二遍求出f[i]表示以i为根的树的深度和。。
g[i]=sigma(g[k])+size[i]-1(k为i的子树),f[i]=f[fa[i]]+n-size[i]*2
size[i]表示以i为根的子树节点数,fa[i]表示i的父亲。。
#include<cstdio>
struct re{
int u,v;
} a[2000001];
int n,sum=0;
long long f[1000001],g[1000001],size[1000001],fa[1000001];
int head[1000001],next[2000001];
void dfs(int i){
size[i]=1;
g[i]=0;
for (int j=head[i];j;j=next[j]){
int k=a[j].v;
if (k!=fa[i]){
fa[k]=i;
dfs(k);
size[i]+=size[k];
g[i]+=g[k];
}
}
g[i]+=size[i]-1;
}
void dfs2(int i){
if (i!=1){
int j=fa[i];
f[i]=f[j]-size[i]+n-size[i];
//printf("f[%d]=%d\n",i,f[i]);
}
for (int j=head[i];j;j=next[j]){
int k=a[j].v;
if (fa[i]!=k) dfs2(k);
}
}
void build(int u,int v){
a[++sum].u=u;
a[sum].v=v;
next[sum]=head[u];
head[u]=sum;
}
int main(){
scanf("%d",&n);
int u,v;
for (int i=1;i<=n-1;i++){
scanf("%d%d",&u,&v);
build(u,v);
build(v,u);
}
dfs(1);
f[1]=g[1];
dfs2(1);
int j=0;
for (int i=1;i<=n;i++){
//printf("g[%d]=%d\n",i,g[i]);
if (f[i]>f[j]) j=i;
}
printf("%d\n",j);
}
评论 (0)