[POI2008]Sta

[POI2008]Sta

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

这道题看完题面和数据范围应该很明显的是树形dp了。
\(F[i]\)表示当\(i\)的子树(1为根节点时i的子树)的深度和。(\(i\)节点深度视为\(0\))
考虑如何换根转移,由我们状态的定义可得
\[dp[v]=dp[k]-(f[v]+size[v])+n-size[v]+f[v]\]
\(dp[k]-(f[v]+size[v])\)即表示当\(k\)为根时,除v以外的子树的深度和。
加上\(n-size[v]\)是因为当前我们以\(v\)作为根节点,其他节点的深度相对于\(k\)时会\(+1\)。
\(f[v]\)即\(v\)的子树对\(v\)的贡献。
注意long long

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#define lll long long
using namespace std;
lll read()
{
    lll x=0,w=1;char ch=getchar();
    while(ch>'9'||ch<'0') {if(ch=='-')w=-1;ch=getchar();}
    while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
    return x*w;
}
lll n,cnt;
lll head[1000010];
lll dp[1000010],f[1000010],size[1000010];
struct node{
    lll to,next;
}edge[2000010];
void add(lll x,lll y)
{
    cnt++;
    edge[cnt].to=y;
    edge[cnt].next=head[x];
    head[x]=cnt;
}
void dfs(lll k,lll fa,lll depth)
{
    lll v;
    for(lll i=head[k];i;i=edge[i].next)
    {
        v=edge[i].to;
        if(v==fa) continue;
        dfs(v,k,depth+1);
        f[k]+=f[v]+size[v];
        size[k]+=size[v];
    }
    size[k]++;
}
void DP(lll k,lll fa)
{
    lll v;
    for(lll i=head[k];i;i=edge[i].next)
    {
        v=edge[i].to;
        if(v==fa) continue;
        dp[v]=dp[k]-(f[v]+size[v])+n-size[v]+f[v];
        DP(v,k);
    }
}
int main()
{
    lll x,y,pos,ans=0;
    n=read();
    for(lll i=1;i<n;i++)
    {
        x=read();y=read();
        add(x,y);add(y,x);
    }
    dfs(1,0,0);
    dp[1]=f[1];
    DP(1,0);
    for(lll i=1;i<=n;i++)
    {
        if(dp[i]>ans)
        {
            ans=dp[i];
            pos=i;
        }
    }
    cout<<pos;
}

原文地址:https://www.cnblogs.com/lsgjcya/p/9200709.html

时间: 2024-09-28 13:09:10

[POI2008]Sta的相关文章

1131: [POI2008]Sta

1131: [POI2008]Sta Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 783  Solved: 235[Submit][Status] Description 给出一个N个点的树,找出一个点来,以这个点为根的树时,所有点的深度之和最大 Input 给出一个数字N,代表有N个点.N<=1000000 下面N-1条边. Output 输出你所找到的点,如果具有多个解,请输出编号最小的那个. Sample Input 8 1 4 5 6

BZOJ 1131: [POI2008]Sta

1131: [POI2008]Sta Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1370  Solved: 486[Submit][Status][Discuss] Description 给出一个N个点的树,找出一个点来,以这个点为根的树时,所有点的深度之和最大 Input 给出一个数字N,代表有N个点.N<=1000000 下面N-1条边. Output 输出你所找到的点,如果具有多个解,请输出编号最小的那个. Sample Input

[BZOJ1131][POI2008] Sta 树的深度

Description 给出一个N个点的树,找出一个点来,以这个点为根的树时,所有点的深度之和最大 Input 给出一个数字N,代表有N个点.N<=1000000 下面N-1条边. Output 输出你所找到的点,如果具有多个解,请输出编号最小的那个. Sample Input81 45 64 56 76 82 43 4 Sample Output7 题解: 都说是裸树形DP,其实我做的时候就是把它当成搜索去做了,当然是一个意思.假设当前的根为1,先求出每棵子树的大小,以及所有点的深度之和.考虑

[BZOJ1131][POI2008]Sta

题目描述 Description 给出一个N个点的树,找出一个点来,以这个点为根的树时,所有点的深度之和最大 输入描述 Input Description 给出一个数字N,代表有N个点.N<=1000000 下面N-1条边. 输出描述 Output Description 输出你所找到的点,如果具有多个解,请输出编号最小的那个. 样例输入 Sample Input 81 45 64 56 76 82 43 4 样例输出 Sample Output 7 数据范围及提示 Data Size &

BZOJ 1131 POI2008 Sta 树形DP

题目大意:给定一个n个点的无根树,要求找到一个根节点,使深度之和最大 令f[x]为以x为根的子树的深度之和 首先我们找到任意一个节点进行深搜,统计出每棵子树的大小,以及所有点的深度之和 然后再以该节点为根深搜一遍,此时状态从父节点转移至子节点,转移方程如下: 当我们将根节点从4节点变为5节点时,橙色部分每个点的深度+1,绿色部分每个点的深度-1 故得到状态转移方程: f[x]=f[fa[x]]+n-2*size[x] 最后扫一遍数组即可出解 #include<cstdio> #include&

BZOJ1131 [POI2008]Sta 其他

原文链接http://www.cnblogs.com/zhouzhendong/p/8081100.html 题目传送门 - BZOJ1131 题意概括 给出一个N个点的树,找出一个点来,以这个点为根的树时,所有点的深度之和最大. 题解 嘻,这题不卡栈. 假设以1为根 先跑一遍dfs,算出每一个子树的节点数size,同时算出以1为根节点的深度和. 然后再跑一遍dfs,这一回,我们就可以算答案了. 假设我们要把树根从一条边的一个节点移向另一个节点,那么,这两个节点为根的答案差就是这条边两端的节点个

树形DP水题杂记

BZOJ1131: [POI2008]Sta 题意:给出一个N个点的树,找出一个点来,以这个点为根的树时,所有点的深度之和最大. 题解:记录每个点的深度,再根据根节点的深度和逐层推导出其他点的深度和. 我用的是BFS #include <stdio.h> #include <string.h> #include <iostream> #include <queue> using namespace std; typedef long long ll; int

[DynamicProgramming]动态规划题目泛做

Educational Codeforces Round 12 F 大意: 求n(n<=1011)以内恰好有4个因数的数的个数 分析: 首先一个数恰好有4个因数,说明它质因数分解之后是两个质数的乘积或是一个质数的三次方,对于后一种情况我们直接n1/3就能算出来,关键在于计算n以内有多少个数是两个素数的乘积. 设n=p1?p2,则必然有p1<n?√,p2>n?√,我们枚举p1,那么问题就在于np1 内有多少个素数. 这一点我们用dp来解决. 记pj为第j个素数,dp[n][j]为[1,n]

POI2008 题解

POI2008 完结(′?_?`)撒花! 海报PLA 单调栈裸题! 激光发射器SZK 光路可逆? 然后证一下发射器与接收器两两对应? 砖块Klo 区间中值! 可用树状数组水过... 将高度 \( h \) 的值域作为树状数组维护的序列,维护一下前缀数量与前缀和即可. BLO 求割点裸题! Sta so easy 的树上DP! CLO 蜜汁构造... Tro 草稿题... 把差积分开算,求和 枪战Maf 有向仙人掌? naive! 贪心构造即可(<--口胡的) 正解还要分好多种情况? 账本BBB