题目描述
Description
小Q正在设计一种棋类游戏。在小Q设计的游戏中,棋子可以放在棋盘上的格点中。某些格点之间有连线,棋子只能在有连线的格点之间移动。整个棋盘上共有V个格点,编号为0,1,2…,V-1,它们是连通的,也就是说棋子从任意格点出发,总能到达所有的格点。小Q在设计棋盘时,还保证棋子从一个格点移动到另外任一格点的路径是唯一的。小Q现在想知道,当棋子从格点0出发,移动N步最多能经过多少格点。格点可以重复经过多次,但不重复计数。
Input
第一行包含2个正整数V,N,其中V表示格点总数,N表示移动步数。
接下来V-1行,每行两个数Ai,Bi,表示编号为Ai,Bi的两个格点之间有连线。
V,N≤ 100, 0 ≤Ai,Bi<V
Output
输出一行一个整数,表示最多经过的格点数量。
Sample Input
5 2
1 0
2 1
3 2
4 3
Sample Output
3
题目分析:
dfs+贪心 我们先找出树中的最长链 这是一步能到达的 其余的点就是两步 因为还要回到链上 最后根据给你的步数进行分类讨论即可
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int n,m;
int head[500],net[500],to[500],deep[500];
int tot;
void add(int x,int y)
{
net[++tot]=head[x];
head[x]=tot;
to[tot]=y;
}
int tmp;
void dfs(int x,int temp)
{
deep[x]=deep[temp]+1;
tmp=max(tmp,deep[x]);
for(int i=head[x];i;i=net[i])
if(to[i]!=temp) dfs(to[i],x);
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<n;i++)
{
int x,y;
scanf("%d%d",&x,&y);
x++,y++;
add(x,y),add(y,x);
}
deep[1]=-1;
dfs(1,0);
if(m<=tmp) printf("%d",m+1);
else if(m>tmp+2*(n-tmp)) printf("%d",n);
else printf("%d",tmp+1+(m-tmp)/2);
}