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

[BZOJ1131][POI2008]Sta

技術 next hint 深度 ica namespace string isdigit first

題目描述 Description

給出一個N個點的樹,找出一個點來,以這個點為根的樹時,所有點的深度之和最大

輸入描述 Input Description

給出一個數字N,代表有N個點.N<=1000000 下面N-1條邊.

輸出描述 Output Description

輸出你所找到的點,如果具有多個解,請輸出編號最小的那個.

樣例輸入 Sample Input

8
1 4
5 6
4 5
6 7
6 8
2 4
3 4

樣例輸出 Sample Output

7

數據範圍及提示 Data Size & Hint

之前的一些廢話:近日諸事不順。

題解:跟之前某題基本沒有區別,貼題解走人:http://www.cnblogs.com/FYH-SSGSS/p/7017092.html

代碼:

技術分享
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<queue>
#include<cstdio>
using namespace std;
typedef long long LL;
#define mem(a,b) memset(a,b,sizeof(a))
typedef pair
<int,int> PII; inline int read() { int x=0,f=1;char c=getchar(); while(!isdigit(c)){if(c==-)f=-1;c=getchar();} while(isdigit(c)){x=x*10+c-0;c=getchar();} return x*f; } const int maxn=1000010; struct Edge { int u,v,next; Edge() {} Edge(int _1,int _2,int _3):u(_1),v(_2),next(_3) {} }e[maxn
<<1]; int n,ce,a,b,first[maxn],size[maxn]; LL path[maxn],ans[maxn],ANS; void addEdge(int a,int b) { e[++ce]=Edge(a,b,first[a]);first[a]=ce; e[++ce]=Edge(b,a,first[b]);first[b]=ce; } void dfs(int now,int fa) { size[now]=1; for(int i=first[now];i!=-1;i=e[i].next) if(e[i].v!=fa) { dfs(e[i].v,now); size[now]+=size[e[i].v]; path[now]+=(path[e[i].v]+size[e[i].v]); } } void rdfs(int now,int fa) { for(int i=first[now];i!=-1;i=e[i].next) if(e[i].v!=fa)ans[e[i].v]=ans[now]+n-2*size[e[i].v],rdfs(e[i].v,now); } int main() { mem(first,-1); n=read(); for(int i=1;i<n;i++)a=read(),b=read(),addEdge(a,b); dfs(1,0);ans[1]=path[1];rdfs(1,0); for(int i=1;i<=n;i++)ANS=max(ANS,ans[i]); for(int i=1;i<=n;i++)if(ANS==ans[i]){printf("%d\n",i);break;} return 0; }
View Code

總結:

[BZOJ1131][POI2008]Sta