洛谷 P3698 [CQOI2017]小Q的棋盘 解题报告

P3698 [CQOI2017]小Q的棋盘

题目描述

小 Q 正在设计一种棋类游戏。

在小 Q 设计的游戏中,棋子可以放在棋盘上的格点中。某些格点之间有连线,棋子只能在有连线的格点之间移动。整个棋盘上共有 V 个格点,编号为0,1,2 … , V− 1,它们是连通的,也就是说棋子从任意格点出发,总能到达所有的格点。小 Q 在设计棋盘时,还保证棋子从一个格点移动到另外任一格点的路径是唯一的。

小 Q 现在想知道,当棋子从格点 0 出发,移动 N 步最多能经过多少格点。格点可以重复经过多次,但不重复计数。

输入输出格式

输入格式:

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

接下来\(V−1\)行,每行两个数\(a_i,b_i\),表示编号为\(a_i,b_i\)的两个格点之间有连线。

输出格式:

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

说明:

对于 100%的测试点,\(N,V ≤ 100, 0 ≤a_i,b_i< V\)


我贪心算是废了

这个题真的不难想orz...

首先读题,这是一颗树。

然后发现最后一次走可以不回去,最后一次肯定走最长的链

然后其他的点多一次返回的开销


Code:

#include <cstdio>
const int N=102;
int min(int x,int y){return x<y?x:y;}
int head[N],to[N<<1],Next[N<<1],cnt;
void add(int u,int v)
{
    to[++cnt]=v;Next[cnt]=head[u];head[u]=cnt;
}
int mx=0,used[N],n,m;
void dfs(int now,int dep)
{
    used[now]=1;
    mx=mx>dep?mx:dep;
    for(int i=head[now];i;i=Next[i])
    {
        int v=to[i];
        if(!used[v])
            dfs(v,dep+1);
    }
}
int main()
{
    scanf("%d%d",&n,&m);
    int u,v;
    for(int i=1;i<n;i++)
    {
        scanf("%d%d",&u,&v);
        add(u,v),add(v,u);
    }
    dfs(0,1);
    if(m<mx-1)
        printf("%d\n",m+1);
    else
        printf("%d\n",min(n,mx+(m-mx+1)/2));
    return 0;
}


2018.7.11

posted @ 2018-07-11 16:50  露迭月  阅读(197)  评论(0编辑  收藏  举报