bzoj-1131 Sta

题意:

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

n<=1000000;

题解:

其实我做这道题的时候总有一种莫名其妙的即视感怎么回事。。。

算了说不定这道题我真的做过。。。

比较暴力的是将所有点枚举,然后深搜累加所有深度;

但是显然所有点等于父树的点+子树的点;

那么只要求出这两者累加就好了;

子树的总深度简直好求,就是将儿子的总深度+size就好了;

父树的稍微有点麻烦,因为需要一些预处理所以在第二次深搜解决;

对于一个点来说,这个点的父树就是【父亲+父亲的父树+兄弟的子树】;

那么分别累加即可:

注意一下推公式就好; (加减同一项不要消下去。。不然没法调。。)

时间复杂度O(n)

所以就这么一道树形DP傻逼题我还是犯了一堆傻逼错误;

一百万看成十万,公式写错,int输出%lld,更新没判相等。。

对了这题还要开long long,这估计是我唯一没掉进去的坑了= =;

代码:

#include<stdio.h>
#include<string.h>
#include<algorithm>
#define N 1100000
using namespace std;
typedef long long ll;
int n,no,to[N<<1],next[N<<1],head[N],ce;
ll sum[N],size[N],fas[N],ans;
void add(int x,int y)
{
	to[++ce]=y;
	next[ce]=head[x];
	head[x]=ce;
}
void dfs1(int x,int pre)
{
	size[x]=1;
	int i,y;
	for(i=head[x];i;i=next[i])
	{
		if((y=to[i])!=pre)
		{
			dfs1(y,x);
			size[x]+=size[y];
			sum[x]+=sum[y]+size[y];
		}
	}
}
void dfs2(int x,int pre)
{
	int i,y;
	if(x!=1)
	fas[x]=fas[pre]+sum[pre]-sum[x]-size[x]+size[pre]-size[x]-1+n-size[pre]+1;
	if(ans<fas[x]+sum[x])
	{
		ans=fas[x]+sum[x];
		no=x;
	}
	else if(ans==fas[x]+sum[x])
		no=min(no,x);
	for(i=head[x];i;i=next[i])
	{
		if((y=to[i])!=pre)
		{
			dfs2(y,x);
		}
	}
}
int main()
{
	int m,i,j,k,x,y;
	scanf("%d",&n);
	for(i=1;i<n;i++)
	{
		scanf("%d%d",&x,&y);
		add(x,y),add(y,x);
	}
	dfs1(1,0);
	dfs2(1,0);
	printf("%d\n",no);
	return 0;
}
时间: 2024-10-03 13:29:52

bzoj-1131 Sta的相关文章

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

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&

bzoj 1131 简单树形dp

思路:随便想想就能想出来啦把...  卡了我一个vector... #include<bits/stdc++.h> #define LL long long #define fi first #define se second #define mk make_pair #define pii pair<int,int> #define piii pair<int, pair<int,int> > using namespace std; const 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]

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】初级水题列表——献给那些想要进军BZOJ的OIers(自用,怕荒废了最后的六月考试月,刷刷水题,水水更健康)

BZOJ初级水题列表——献给那些想要进军BZOJ的OIers 代码长度解释一切! 注:以下代码描述均为C++ RunID User Problem Result Memory Time Code_Length 695765 Eolv 1000 Accepted 804 kb 0 ms 118 B 739478 Eolv 2463 Accepted 804 kb 0 ms 134 B 696662 Eolv 1968 Accepted 1272 kb 48 ms 137 B 739546 Eolv

二分+最短路判定 BZOJ 2709: [Violet 1]迷宫花园

BZOJ 2709: [Violet 1]迷宫花园 Sample Input 5 10.28 9 9 ######### # # # # # # # #S# # ##### # # ## # # # ### ### ##E # ######### 4.67 9 9 ######### # ## ## ### #S# # # # E ## # # ##### # ## ### # ##### # # # # ######### 39.06 9 9 ######### # # # # # # # #

bzoj 1822: [JSOI2010]Frozen Nova 冷冻波 题解

[原题] 1822: [JSOI2010]Frozen Nova 冷冻波 Time Limit: 10 Sec  Memory Limit: 64 MB Submit: 796  Solved: 218 [Submit][Status] Description WJJ喜欢"魔兽争霸"这个游戏.在游戏中,巫妖是一种强大的英雄,它的技能Frozen Nova每次可以杀死一个小精灵.我们认为,巫妖和小精灵都可以看成是平面上的点. 当巫妖和小精灵之间的直线距离不超过R,且巫妖看到小精灵的视线没

BZOJ 1013: [JSOI2008]球形空间产生器sphere

二次联通门 : BZOJ 1013: [JSOI2008]球形空间产生器sphere /* BZOJ 1013: [JSOI2008]球形空间产生器sphere 高斯消元 QAQ SB的我也能终于能秒题了啊 设球心的坐标为(x,y,z...) 那么就可以列n+1个方程,化化式子高斯消元即可 */ #include <cstdio> #include <iostream> #include <cstring> #define rg register #define Max

bzoj 3309 DZY Loves Math - 莫比乌斯反演 - 线性筛

对于正整数n,定义f(n)为n所含质因子的最大幂指数.例如f(1960)=f(2^3 * 5^1 * 7^2)=3, f(10007)=1, f(1)=0. 给定正整数a,b,求sigma(sigma(f(gcd(i,j)))) (i=1..a, j=1..b). Input 第一行一个数T,表示询问数. 接下来T行,每行两个数a,b,表示一个询问. Output 对于每一个询问,输出一行一个非负整数作为回答. Sample Input 4 7558588 9653114 6514903 445