bzoj 1131: [POI2008]Sta(树形DP)

来源:互联网 发布:陕西网络广播 编辑:程序博客网 时间:2024/05/17 08:21

1131: [POI2008]Sta

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 1140  Solved: 373
[Submit][Status][Discuss]

Description

给出一个N个点的树,找出一个点来,以这个点为根的树时,所有点的深度之和最大

Input

给出一个数字N,代表有N个点.N<=1000000 下面N-1条边.

Output

输出你所找到的点,如果具有多个解,请输出编号最小的那个.

Sample Input

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

Sample Output

7

HINT

Source

[Submit][Status][Discuss]

题解: 先把1当作根求出总和,然后转移即可。

#include<iostream>#include<cstdio>#include<cstring>#include<cmath>#include<algorithm>#define  N 2000003using namespace std;int n,m;int point[N],next[N],v[N],deep[N],tot,size[N];long long f[N],ans;int ansx;void add(int x,int y){tot++; next[tot]=point[x]; point[x]=tot; v[tot]=y;tot++; next[tot]=point[y]; point[y]=tot; v[tot]=x;  }void dfs(int x,int fa){size[x]=1;for (int i=point[x];i;i=next[i]) if (v[i]!=fa)  {  dfs(v[i],x);  deep[v[i]]=deep[x]+1;  size[x]+=size[v[i]];  }}void dp(int x,int fa){for (int i=point[x];i;i=next[i]) if (v[i]!=fa)  {  f[v[i]]=(long long)f[x]-(long long)size[v[i]]+(long long)n-size[v[i]];  if (ans<f[v[i]])   ans=f[v[i]],ansx=v[i];  if (ans==f[v[i]]&&ansx>v[i])   ansx=v[i];  dp(v[i],x);  }}int main(){scanf("%d",&n);for (int i=1;i<n;i++) { int x,y; scanf("%d%d",&x,&y); add(x,y); }deep[1]=1;dfs(1,0);for (int i=1;i<=n;i++) f[1]+=(long long)deep[i];ans=f[1],ansx=1;dp(1,0);printf("%d\n",ansx);}



0 0
原创粉丝点击