BZOJ 1131: [POI2008]Sta
题目大意:给出一个N个点的树,找出一个点来,以这个点为根的树时,所有点的深度之和最大
题解:首先以1为根统计一次答案,然后每次O(1)换根统计答案
代码:
#include<cstdio> using namespace std; int n,cnt,ansid,last[1000005]; long long ans,sz[1000005],f[1000005]; struct node{ int to,next; }e[2000005]; void add(int a,int b){ e[++cnt].to=b; e[cnt].next=last[a]; last[a]=cnt; } void dfs1(int x,int fa){ sz[x]=1; f[x]=1; for (int i=last[x]; i; i=e[i].next){ int V=e[i].to; if (V==fa) continue; dfs1(V,x); sz[x]+=sz[V]; f[x]+=f[V]+sz[V]; } } void dfs2(int x,int fa,long long lastsum){ long long sum=f[x]+lastsum+n-sz[x]; if (sum>ans || sum==ans && x<ansid){ ans=sum; ansid=x; } long long ssum=0; for (int i=last[x]; i; i=e[i].next){ int V=e[i].to; if (V==fa) continue; ssum+=f[V]+sz[V]; } ssum+=lastsum+n-sz[x]; for (int i=last[x]; i; i=e[i].next){ int V=e[i].to; if (V==fa) continue; dfs2(V,x,ssum-(f[V]+sz[V])+1); } } int main(){ scanf("%d",&n); for (int i=1; i<n; i++){ int x,y; scanf("%d%d",&x,&y); add(x,y); add(y,x); } dfs1(1,0); ans=f[1],ansid=1; dfs2(1,0,0); printf("%d\n",ansid); return 0; }