• BZOJ_4813_[Cqoi2017]小Q的棋盘_dfs


    BZOJ_4813_[Cqoi2017]小Q的棋盘_dfs

    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
    从格点 0 出发移动 2 步。经过 0, 1, 2 这 3 个格点。
     

    分析:
    对于经过的每个点,要么走一次,要么走两次,并且要让走一次的点尽可能地多。
    发现走一次的点一定是从根到叶子的一条路径,找到整棵树最大的$dep$ 即可。
    再判断一下是否能走到路径的末尾。
     
    代码:
    #include <stdio.h>
    #include <string.h>
    #include <algorithm>
    using namespace std;
    #define N 1050
    int head[N],to[N<<1],nxt[N<<1],cnt,n,m,dep[N],maxdep;
    inline void add(int u,int v) {
        to[++cnt]=v; nxt[cnt]=head[u]; head[u]=cnt;
    }
    void dfs(int x,int y) {
        dep[x]=dep[y]+1;
        maxdep=max(maxdep,dep[x]);
        int i;
        for(i=head[x];i;i=nxt[i]) {
            if(to[i]!=y) {
                dfs(to[i],x);
            }
        }
    }
    int main() {
        scanf("%d%d",&n,&m);
        int i,x,y;
        for(i=1;i<n;i++) {
            scanf("%d%d",&x,&y);
            x++; y++;
            add(x,y); add(y,x);
        }
        dep[0]=-1;
        dfs(1,0);
        if(m<=maxdep) {
            printf("%d
    ",m+1); return 0;
        }
        printf("%d
    ",min(n,maxdep+(m-maxdep)/2+1));
    }
    
  • 相关阅读:
    js数组求交集
    php安装oci8和pdo_oci扩展实现连接oracle数据库
    nginx配置静态资源压缩
    SHELL递归遍历文件夹下所有文件
    PHP函数获取临时文件目录
    php去除文件bom头
    tcpdump抓取udp报文
    linux获取当前运行级别
    当安装软件后提示依赖没有安装时
    Ubuntu卸载通过apt-get命令安装的软件
  • 原文地址:https://www.cnblogs.com/suika/p/8890607.html
Copyright © 2020-2023  润新知