[BZOJ1131][POI2008]Sta


题目描述 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;
}

总结:

时间: 2024-10-24 22:11:18

[BZOJ1131][POI2008]Sta的相关文章

[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 其他

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

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

[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为根节点

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&

树形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]

bzoj-1131 Sta

题意: 给出一个n个点的树,找出一个点来,使以这个点为根的树所有点的深度之和最大: n<=1000000: 题解: 其实我做这道题的时候总有一种莫名其妙的即视感怎么回事... 算了说不定这道题我真的做过... 比较暴力的是将所有点枚举,然后深搜累加所有深度: 但是显然所有点等于父树的点+子树的点: 那么只要求出这两者累加就好了: 子树的总深度简直好求,就是将儿子的总深度+size就好了: 父树的稍微有点麻烦,因为需要一些预处理所以在第二次深搜解决: 对于一个点来说,这个点的父树就是[父亲+父亲的