[BZOJ4813] [CQOI2017]小Q的棋盘

题目描述

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);
}

 

发表评论

邮箱地址不会被公开。 必填项已用*标注