1. 程式人生 > >BZOJ1131: [POI2008]Sta

BZOJ1131: [POI2008]Sta

sum UC i++ () scan poi2008 題目 poi clu

題目大意:給出一個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; }

BZOJ1131: [POI2008]Sta