Sta bzoj-1131 POI-2008
题目大意:给定一棵n个点的树,求一个根,使得深度和最大。
注释:$1le n le 10^6$。
想法:扭一扭即可。
扭的时候看看这个点当没当过根。
最后,附上丑陋的代码... ...
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #define N 1000010 using namespace std; typedef long long ll; int to[N<<1],nxt[N<<1],head[N],tot,size[N],dis[N],n; ll val[N],ans=0; int now; inline char nc() { static char buf[100000],*p1,*p2; return (p1==p2)&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++; } int read() { int x=0; char c=nc(); while(!isdigit(c)) c=nc(); while(isdigit(c)) x=(x<<1)+(x<<3)+c-'0',c=nc(); return x; } inline void add(int x,int y) { to[++tot]=y; nxt[tot]=head[x]; head[x]=tot; } void dfs(int pos,int fa) { size[pos]=1,dis[pos]=dis[fa]+1; for(int i=head[pos];i;i=nxt[i]) { if(to[i]==fa) continue; dfs(to[i],pos); size[pos]+=size[to[i]]; } } void dispose(int pos,int fa) { val[pos]=val[fa]-size[pos]+(n-size[pos]); for(int i=head[pos];i;i=nxt[i]) { if(to[i]==fa) continue; dispose(to[i],pos); } } int main() { n=read(); for(int x,y,i=1;i<n;i++) { x=read(); y=read(); add(x,y); add(y,x); } dfs(1,1); for(int i=1;i<=n;i++) val[1]+=dis[i]/* ,printf("%d ",dis[i]) */; dispose(1,1); for(int i=1;i<=n;i++) if(val[i]>ans) ans=val[i],now=i; printf("%d ",now); return 0; }
小结:有意思... ...