【bzoj4813】[Cqoi2017]小Q的棋盘 dfs+贪心

题目描述

小Q正在设计一种棋类游戏。在小Q设计的游戏中,棋子可以放在棋盘上的格点中。某些格点之间有连线,棋子只能在有连线的格点之间移动。整个棋盘上共有V个格点,编号为0,1,2…,V-1,它们是连通的,也就是说棋子从任意格点出发,总能到达所有的格点。小Q在设计棋盘时,还保证棋子从一个格点移动到另外任一格点的路径是唯一的。小Q现在想知道,当棋子从格点0出发,移动N步最多能经过多少格点。格点可以重复经过多次,但不重复计数。

输入

第一行包含2个正整数V,N,其中V表示格点总数,N表示移动步数。

接下来V-1行,每行两个数Ai,Bi,表示编号为Ai,Bi的两个格点之间有连线。

V,N≤100, 0 ≤Ai,Bi<V

输出

输出一行一个整数,表示最多经过的格点数量。

样例输入

5 2

1 0

2 1

3 2

4 3

样例输出

3



题解

dfs+贪心

先dfs求出以0为起点的最长一条链,这条链上的点只经过一次,消耗1步;其它的点经过后需要返回这条链上,消耗2步。

然后分类讨论是否能走完链和走完树即可。

#include <cstdio>
#define N 110
int head[N] , to[N << 1] , next[N << 1] , cnt , deep[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;
	for(i = head[x] ; i ; i = next[i])
		if(to[i] != fa)
			deep[to[i]] = deep[x] + 1 , dfs(to[i] , x);
}
int main()
{
	int n , p , i , x , y , l = 0;
	scanf("%d%d" , &n , &p);
	for(i = 1 ; i < n ; i ++ )
		scanf("%d%d" , &x , &y) , add(x , y) , add(y , x);
	dfs(0 , -1);
	for(i = 1 ; i < n ; i ++ )
		if(l < deep[i])
			l = deep[i];
	if(p <= l) printf("%d\n" , p + 1);
	else if(p >= l + 2 * (n - l - 1)) printf("%d\n" , n);
	else printf("%d\n" , l + (p - l) / 2 + 1);
	return 0;
}
时间: 2024-10-29 00:06:20

【bzoj4813】[Cqoi2017]小Q的棋盘 dfs+贪心的相关文章

【BZOJ】 4813: [Cqoi2017]小Q的棋盘

题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=4813 暴力转移就好,考虑以某一个点为根的子树分为是否走回来两种情况 ${f_{i,j}}$表示已点$i$为根的子树,走了$j$步之后回到点$i$最多能经过多少个点 ${g_{i,j}}$表示已点$i$为根的子树,走了$j$步之后不管停在那个点最多能经过多少个点 写了个${n^{2}}$转移 1 #include<iostream> 2 #include<algorithm>

BZOJ [Cqoi2017] 小Q的棋盘

题解:枚举最后在哪里停止,然后剩下的步数/2 也就是找最大深度 枚举终止位置算是一种思路吧 #include<iostream> #include<cstdio> #include<cstring> using namespace std; const int maxn=10009; int n,m; int maxdep; int cntedge; int head[maxn]; int to[maxn<<1],nex[maxn<<1]; vo

[CQOI2017]小Q的棋盘

https://zybuluo.com/ysner/note/1218474 题面 一棵有\(n\)个结点的树,问从\(1\)(根)结点出发,走\(m\)步最多能经过多少结点. \(n\leq100\) 解析 数据范围亮了 显然,在根结点周围转一圈再回来,走最长链到底是最值的. 于是先求出最长链\(L\). 如果\(L>m\),\(ans=m+1\); 否则剩下\(n-(L-1)\)步,能多走\(\frac{n-L+1}{2}\)个点.(画画图发现找不出什么特殊情况) 即\[ans=min(n,

20191110luogu3698小Q的棋盘 | 树形背包dp | 贪心

luogu3698小Q的棋盘 题意: 求从树的根节点出发,走n步能经过的最多的点的数量(可以重复走点,但是重复走的步数会记录) 树形背包dp: 对于从0出发,我们可以这样走: 1.选一条岔路一直走下去 2.选一条岔路走后回到0点,再选一条岔路走下去 对应的dp转移: f[0][u][j]代表从u出发走j步不一定回到u点能到达的最大步数 f[1][u][j]代表从u出发走j步回到u点能到达的最大步数 f[0][u][j] = max(f[0][u][j],f[0][u][k] + f[1][too

重庆OI2017 小 Q 的棋盘

小 Q 的棋盘 时间限制: 1 Sec  内存限制: 512 MB 题目描述 小Q正在设计一种棋类游戏.在小Q设计的游戏中,棋子可以放在棋盘上的格点中.某些格点之间有连线,棋子只能在有连线的格点之间移动.整个棋盘上共有V个格点,编号为0,1,2…,V-1,它们是连通的,也就是说棋子从任意格点出发,总能到达所有的格点.小Q在设计棋盘时,还保证棋子从一个格点移动到另外任一格点的路径是唯一的.小Q现在想知道,当棋子从格点0出发,移动N步最多能经过多少格点.格点可以重复经过多次,但不重复计数. 输入 第

bzoj4814: [Cqoi2017]小Q的草稿

Description 小Q是个程序员.众所周知,程序员在写程序的时候经常需要草稿纸.小Q现在需要一张草稿纸用来画图,但是桌上 只有一张草稿纸,而且是一张被用过很多次的草稿纸.草稿纸可以看作一个二维平面,小Q甚至已经给它建立了直 角坐标系.以前每一次草稿使用过的区域,都可以近似的看作一个平面上的一个三角形,这个三角形区域的内部和 边界都不能再使用.当然了,以前的草稿也没有出现区域重叠的情况.小Q已经在草稿纸上画上了一些关键点,这 些关键点都在没使用过的区域.小Q想把这些关键点两两之间尽可能的用线

[bzoj4815] [洛谷P3700] [Cqoi2017] 小Q的表格

Description 小Q是个程序员. 作为一个年轻的程序员,小Q总是被老C欺负,老C经常把一些麻烦的任务交给小Q来处理. 每当小Q不知道如何解决时,就只好向你求助.为了完成任务,小Q需要列一个表格,表格 有无穷多行,无穷多列,行和列都从1开始标号.为了完成任务,表格里面每个格子都填了 一个整数,为了方便描述,小Q把第a行第b列的整数记为f(a,b),为了完成任务,这个表格要 满足一些条件: (1)对任意的正整数a,b,都要满足f(a,b)=f(b,a): (2)对任意的正整数a,b,都要 满

解题:CQOI 2017 小Q的棋盘

题面 由树的结构我们可以知道,最终要么是连一条(最长的)链都没走完,要么是走了一些点最后走了最长的链.为什么总是说最长的链呢,因为在树上这样走的过程中(最后不要求返回的话)除了一条链都会被走两次,显然我们贪心地把最长链走一次即可. 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 const int N=105; 6 int n,m,t1,t2,cn

BZOJ 4815: [Cqoi2017]小Q的表格

Description \(b×f(a,a+b)=(a+b)*f(a,b)\),支持修改 求\(\sum_{i=1}^k\sum_{j=1}^kf(i,j)\) \(m\leqslant 10^4,k\leqslant n\leqslant 4\times 10^6\) Solution 数论+分块 可以发现这是一个类似于更相减损的东西...就是修改一个位置,只会影响与他横纵坐标相同的位置...所以它其实是一个一维的东西...所以就是求\(\sum_{i=1}^k\sum_{j=1}^k\fra