题目描述

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

输入

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

输出

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

样例输入

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


题解

树形dp

f[x]表示子树i中所有点到点x的距离之和。

g[x]表示整个树中所有点到点x的距离之和。

然后我们发现f和g都是可以递推求出来的,并且f[1]=g[1]。

于是可以先求f[x],f[x]=∑(f[to[i]]+si[to[i]])。

因为这些点到x的距离比到to[i]多1,总共有si[to[i]]个点,所以加上si[to[i]]。

然后g[1]=f[1],再递推求g[to[i]],g[to[i]]=g[x]+n-2*si[to[i]]。

因为有n-si[to[i]]个点到to[i]的距离比到x多1,所以加n-si[to[i]];有si[to[i]]个点到to[i]的距离比到x少1,所以再减si[to[i]],最后就是g[x]+n-2*si[to[i]]。

最后求g[x]的最大值即可。

#include <cstdio>
int n , head[1000001] , to[2000001] , next[2000001] , cnt;
long long si[1000001] , f[1000001] , g[1000001];
void add(int x , int y)
{
to[++cnt] = y;
next[cnt] = head[x];
head[x] = cnt;
}
void dfs1(int x , int fa)
{
int i;
si[x] = 1;
for(i = head[x] ; i ; i = next[i])
{
if(to[i] != fa)
{
dfs1(to[i] , x);
si[x] += si[to[i]];
f[x] += f[to[i]] + si[to[i]];
}
}
}
void dfs2(int x , int fa)
{
int i;
for(i = head[x] ; i ; i = next[i])
{
if(to[i] != fa)
{
g[to[i]] = g[x] + n - 2 * si[to[i]];
dfs2(to[i] , x);
}
}
}
int main()
{
int i , x , y , ans = 0;
scanf("%d" , &n);
for(i = 1 ; i < n ; i ++ )
scanf("%d%d" , &x , &y) , add(x , y) , add(y , x);
dfs1(1 , 0);
g[1] = f[1];
dfs2(1 , 0);
for(i = 1 ; i <= n ; i ++ )
if(g[ans] < g[i])
ans = i;
printf("%d\n" , ans);
return 0;
}

【bzoj1131】[POI2008]Sta 树形dp的更多相关文章

  1. BZOJ1131[POI2008]Sta——树形DP

    题目描述 给出一个N个点的树,找出一个点来,以这个点为根的树时,所有点的深度之和最大 输入 给出一个数字N,代表有N个点.N<=1000000 下面N-1条边. 输出 输出你所找到的点,如果具有 ...

  2. 【BZOJ-1131】Sta 树形DP

    1131: [POI2008]Sta Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1150  Solved: 378[Submit][Status] ...

  3. [bzoj1131][POI2008]Sta_树形dp

    Sta bzoj-1131 POI-2008 题目大意:给定一棵n个点的树,求一个根,使得深度和最大. 注释:$1\le n \le 10^6$. 想法:扭一扭即可. 扭的时候看看这个点当没当过根. ...

  4. bzoj 1131 [POI2008]Sta 树形dp 转移根模板题

    [POI2008]Sta Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1889  Solved: 729[Submit][Status][Discu ...

  5. BZOJ1131 POI2008 Sta 【树形DP】

    BZOJ1131 POI2008 Sta Description 给出一个N个点的树,找出一个点来,以这个点为根的树时,所有点的深度之和最大 Input 给出一个数字N,代表有N个点.N<=10 ...

  6. Bzoj 1131[POI2008]STA-Station (树形DP)

    Bzoj 1131[POI2008]STA-Station (树形DP) 状态: 设\(f[i]\)为以\(i\)为根的深度之和,然后考虑从他父亲转移. 发现儿子的深度及其自己的深度\(-1\) 其余 ...

  7. [BZOJ1131][POI2008] Sta 树的深度

    Description 给出一个N个点的树,找出一个点来,以这个点为根的树时,所有点的深度之和最大 Input 给出一个数字N,代表有N个点.N<=1000000 下面N-1条边. Output ...

  8. [BZOJ1131/POI2008]Sta树的深度

    Description 给出一个N个点的树,找出一个点来,以这个点为根的树时,所有点的深度之和最大 Input 给出一个数字N,代表有N个点.N<=1000000 下面N-1条边. Output ...

  9. bzoj1131: [POI2008]Sta

    思路:首先先求出以1为根的答案,然后考虑由i转移到i的儿子的答案的变化,显然以son[i]为根的子树的所有结点的深度都会减一,其余的点的深度都会加一,然后就可以直接O(n)求出所有结点的答案,然后取m ...

随机推荐

  1. PIE currently adds full or partial support to IE 6 through 8 for the following CSS3 features

    PIE stands for Progressive Internet Explorer. It is an IE attached behavior which, when applied to a ...

  2. java随笔一(关于定时任务)

    public class ThreadTest { class MyTask implements Runnable{ public void run() { say(); } } public vo ...

  3. 北京Uber优步司机奖励政策(1月6日)

    滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...

  4. 北京Uber优步司机奖励政策(12月14日)

    滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...

  5. Ruby on Rails Tutorial 第2版 学习笔记

    Ruby on Rails Tutorial 第2版 在线阅读:http://railstutorial-china.org/ 英文版:http://ruby.railstutorial.org/ru ...

  6. STM32堆栈指针疑问

    1. 下面的代码看的不是很明白,百为stm32开发板光盘\测试程序\CortexM3\Mode_Privilege\project,堆是程序员分配和使用的,栈是编译器指定的,存放函数参数,临时变量. ...

  7. mongdb数据迁移导出与导入

    导出: mongoexport --host localhost --port --username un1 --password pwd1 --db db1 --collection col1 -- ...

  8. Qt-网络与通信-获取本机网络信息

    在网络应用中,经常需要获取本机主机名和IP地址和硬件地址等信息.运用QHostInfo.QNetworkInterface.QNetworkAddressEntry可以获得本机的网络信息. 上运行截图 ...

  9. Sysbench安装步骤及详情

    Sysbench安装步骤及详情 Sysbench是压力测试工具,可以测试系统的CPU,内存,I/O等,也可以用于数据库的性能测试 Sysbench安装步骤: 安装具体分为Ubuntu16.04和Cen ...

  10. 交换学生 (Foreign Exchange,UVa10763)

    题目描述: 解题思路: 开一个数组,读入一次交换两个数,如果最后数组不变,即符合匹配 #include<iostream> #include<cstdio> #include& ...