【bzoj3522】[Poi2014]Hotel 树形dp

题目描述

有一个树形结构的宾馆,n个房间,n-1条无向边,每条边的长度相同,任意两个房间可以相互到达。吉丽要给他的三个妹子各开(一个)房(间)。三个妹子住的房间要互不相同(否则要打起来了),为了让吉丽满意,你需要让三个房间两两距离相同。
有多少种方案能让吉丽满意?

输入

第一行一个数n。
接下来n-1行,每行两个数x,y,表示x和y之间有一条边相连。

输出

让吉丽满意的方案数。

样例输入

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

样例输出

5



题解

树形dp

如果树上三个点之间两两距离相同,那么距离一定为偶数,且这三条路径的中点重合。

那么我们可以枚举这个中点,要求的就是选出三个点到这个中点距离相同的方案数。

设f1[i]表示选出1个深度为i的点的方案数,f2[i]表示选出2个深度为i的点的方案数,f3[i]表示选出3个深度为i的点的方案数。

然后树形dp乱搞就行了。

注意清空数组不能使用memset,必须要动态清空。

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define N 5010
typedef long long ll;
int n , head[N] , to[N << 1] , next[N << 1] , cnt , deep[N] , md;
ll f1[N] , f2[N] , f3[N] , g[N];
void add(int x , int y)
{
	to[++cnt] = y , next[cnt] = head[x] , head[x] = cnt;
}
void dfs(int x , int fa)
{
	int i;
	md = max(md , deep[x]) , g[deep[x]] ++ ;
	for(i = head[x] ; i ; i = next[i])
		if(to[i] != fa)
			deep[to[i]] = deep[x] + 1 , dfs(to[i] , x);
}
ll query(int x)
{
	int i , j;
	ll sum = 0;
	memset(f1 , 0 , sizeof(f1)) , memset(f2 , 0 , sizeof(f2)) , memset(f3 , 0 , sizeof(f3));
	for(i = head[x] ; i ; i = next[i])
	{
		deep[to[i]] = md = 1 , dfs(to[i] , x);
		for(j = md ; j ; j -- ) f3[j] += f2[j] * g[j] , f2[j] += f1[j] * g[j] , f1[j] += g[j] , g[j] = 0;
	}
	for(i = 1 ; i <= n ; i ++ ) sum += f3[i];
	return sum;
}
int main()
{
	int i , x , y;
	ll ans = 0;
	scanf("%d" , &n);
	for(i = 1 ; i < n ; i ++ ) scanf("%d%d" , &x , &y) , add(x , y) , add(y , x);
	for(i = 1 ; i <= n ; i ++ ) ans += query(i);
	printf("%lld\n" , ans);
	return 0;
}
时间: 2024-10-28 12:26:48

【bzoj3522】[Poi2014]Hotel 树形dp的相关文章

3522: [Poi2014]Hotel( 树形dp )

枚举中点x( 即选出的三个点 a , b , c 满足 dist( x , a ) = dist( x , b ) = dist( x , c ) ) , 然后以 x 为 root 做 dfs , 显然两个位于 x 的同一颗子树内的点是不可能被同时选到的 . 我们对 x 的每一颗子树进行 dfs , 记录下当前子树中的点到 x 距离为 d ( 1 <= d <= n ) 有多少个 , 记为 cnt[ 0 ][ i ] . 然后 cnt[ 1 ][ i ] 记录之前 dfs 过的子树的 cnt[

【BZOJ3522】【BZOJ4543】【POI2014】Hotel 树形DP 长链剖分 启发式合并

题目大意 ? 给你一棵树,求有多少个组点满足\(x\neq y,x\neq z,y\neq z,dist_{x,y}=dist_{x,z}=dist_{y,z}\) ? \(1\leq n\leq 100000\) 题解 ? 问题转换为有多少个组点满足\(dist_{i,x}=dist_{i,y}=dist_{i,z}\) ? 我们考虑树形DP ? \(f_{i,j}=\)以\(i\)为根的子树中与\(i\)的距离为\(j\)的节点数 ? \(g_{i,j}=\)以\(i\)为根的子树外选择一个

bzoj3522 [Poi2014]Hotel

题目链接 在黄学长博客上居然分类树形DP? 暴力,以每个点为根计算子树内答案,推推式子就维护两个S就可以啦 1 #include<algorithm> 2 #include<iostream> 3 #include<cstdlib> 4 #include<cstring> 5 #include<cstdio> 6 #include<string> 7 #include<cmath> 8 #include<ctime&

BZOJ 3829 Poi2014 FarmCraft 树形DP+贪心

题目大意:给定一棵树,从1号节点出发对树进行欧拉遍历,每到达一个点这个点就开始装MC,每个点装MC的时间不同,最后回到1号节点装MC,求所有人都能联机的最少时间 令f[x]为对第x个节点进行欧拉遍历的时间,g[x]为对第x个节点进行欧拉遍历并完成所有节点的装机的最小时间 那么在每个节点以什么顺序遍历每棵子树呢? 我们发现装机多出来的时间 即g[x]-f[x]可以用来遍历其它子树 那么显然要从g[x]-f[x]大的子树开始遍历 因此对每个节点的子树按照g[x]-f[x]递减排个序即可 时间复杂度O

BZOJ3522——[Poi2014]Hotel

1.题意:http://www.lydsy.com/JudgeOnline/problem.php?id=3522 2.分析:这道题有两种情况,第一个是三个点在同一个链上,这显然不可能了,因为树上的路径是唯一的,第二个情况是三个点距离某个中心的距离相等 那么我们只需枚举中间点,然后在不同子树中dfs一下即可求出答案 #include <queue> #include <cstdio> #include <cstring> #include <cstdlib>

BZOJ 3522 POI 2014 Hotel 树形DP

题目大意 给出一棵树,问选择三个点,使得这三个点相互的距离相等的方案有多少种. 思路 这三个点肯定不能再一条链上, 那么就肯定能够确定一个中心点,使得三个点到这个中心点的距离都相等. 之后我们就可以枚举这个中心点,对于每个深度统计一下就可以了.虽然看起来像是O(n3)的,但是跑的飞起啊. CODE #define _CRT_SECURE_NO_WARNINGS #include <cstdio> #include <cstring> #include <iostream>

[bzoj3829][Poi2014]FarmCraft_树形dp

FarmCraft 题目链接:https://lydsy.com/JudgeOnline/problem.php?id=3829 数据范围:略. 题解: 因为每条边只能必须走两次,所以我们的路径一定是进入了一棵子树然后出来,不可能再进去. 我们根据这个性质,设计出状态$f_i$表示以$i$为根的子树答案即可. 转移时,我们发现需要对儿子进行一个排序,我们就暴力的判断一下哪个儿子在前面更优即可. 代码: #include <bits/stdc++.h> #define N 1000010 usi

树形DP水题系列(1):FAR-FarmCraft [POI2014][luogu P3574]

题目 大意: 边权为1 使遍历树时到每个节点的时间加上点权的最大值最小 求这个最小的最大值 思路: 最优化问题 一眼树形DP 考虑状态设立 先直接以答案为状态 dp[u] 为遍历完以u为根的子树的答案 再考虑状态转移 dp[u]=MAX(dp[to]+1,siz+dp[to]);siz为枚举子树到以to为节点的子树时之前已遍历的总时间 很明显这个转移过来的dp值的最优化依赖于子树遍历的顺序 所以我们需要找到一种最优的子树遍历顺序来使每个子树得到最优的dp值来更新 我们通过观察可以发现 交换任意两

3522: [Poi2014]Hotel

3522: [Poi2014]Hotel Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 253  Solved: 117[Submit][Status][Discuss] Description 有一个树形结构的宾馆,n个房间,n-1条无向边,每条边的长度相同,任意两个房间可以相互到达.吉丽要给他的三个妹子各开(一个)房(间).三个妹子住的房间要互不相同(否则要打起来了),为了让吉丽满意,你需要让三个房间两两距离相同.有多少种方案能让吉丽满意?