BZOJ1131: [POI2008]Sta
阿新 • • 發佈:2018-04-05
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