题目:
分析:
这个有点过于简单,两次Dfs处理出Dp[i],Son[i],Deep[i],Val[i](分别表示以1为根时i所有子树的深度之和,以1为根时i子树节点个数,以1为根时i深度,以i为根时的)就好了,然后从Val里面找就可以了,复杂度n,直接过掉。这一题时限是10000ms,没错是10000ms,没准常数小一点的nlogn都能过掉,当然好像用不到。
代码:
#include <cstdio> const int maxn=1000000+10; struct E{ int to; int next; E(){ to=next=0; } }ed[maxn*2]; int head[maxn]; int tot; void J(int a,int b){ tot++; ed[tot].to=b; ed[tot].next=head[a]; head[a]=tot; } int De[maxn]; int er[maxn]; long long Dp[maxn]; int n; long long val[maxn]; long long ans; void Dfs1(int x,int fa){ De[x]=De[fa]+1; Dp[x]=De[x]; for(int i=head[x];i;i=ed[i].next){ if(ed[i].to==fa) continue; Dfs1(ed[i].to,x); er[x]+=er[ed[i].to]+1; Dp[x]+=Dp[ed[i].to]; } } void Dfs2(int x,int fa){ if(x==1) val[x]=Dp[x]; else val[x]=Dp[x]-((long long)De[x]-(long long)1)*((long long)er[x]+(long long)1)+val[fa]-Dp[x]+((long long)De[x]-(long long)2)*((long long)er[x]+(long long)1)+(long long)n-(long long)er[x]-(long long)1;//多转转 for(int i=head[x];i;i=ed[i].next) if(ed[i].to!=fa) Dfs2(ed[i].to,x); } int main(){ scanf("%d",&n); int js1,js2; for(int i=1;i<=n-1;i++){ scanf("%d%d",&js1,&js2); J(js1,js2); J(js2,js1); } Dfs1(1,0); ans=Dp[1]; Dfs2(1,0); int js=1; for(int i=1;i<=n;i++){ if(val[i]>ans){ ans=val[i]; js=i; } } printf("%d",js); return 0; }