二次扫描+换根
有点困思路不清晰啊
#include<cstdio> #include<iostream> #include<cstring> #include<cstdlib> #include<algorithm> #include<cmath> using namespace std; typedef long long LL; struct node { int x,y,next; }a[2100000];int len,last[1100000]; void ins(int x,int y) { len++; a[len].x=x;a[len].y=y; a[len].next=last[x];last[x]=len; } int fa[1100000],dep[1100000],tot[1100000]; LL sum[1100000]; void dfs(int x) { tot[x]=1; for(int k=last[x];k;k=a[k].next) { if(a[k].y!=fa[x]) { fa[a[k].y]=x; dep[a[k].y]=dep[x]+1; dfs(a[k].y); sum[x]+=sum[a[k].y]+tot[a[k].y]; tot[x]+=tot[a[k].y]; } } } LL mmax,now,cnt;int id; void changert(int x) { if(now+sum[x]>mmax) mmax=now+sum[x],id=x; else if(now+sum[x]==mmax)id=min(id,x); for(int k=last[x];k;k=a[k].next) { if(a[k].y!=fa[x]) { cnt+=tot[x]-tot[a[k].y]; now+=(sum[x]-(sum[a[k].y]+tot[a[k].y]))+cnt; changert(a[k].y); now-=(sum[x]-(sum[a[k].y]+tot[a[k].y]))+cnt; cnt-=tot[x]-tot[a[k].y]; } } } int main() { freopen("a.in","r",stdin); freopen("a.out","w",stdout); int n,x,y; scanf("%d",&n); len=0;memset(last,0,sizeof(last)); for(int i=1;i<n;i++) { scanf("%d%d",&x,&y); ins(x,y),ins(y,x); } fa[1]=0;dep[1]=1;dfs(1); mmax=0,id=(1<<30),now=0,cnt=0; changert(1); printf("%d ",id); return 0; }