zoukankan      html  css  js  c++  java
  • 【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
    " , p + 1);
    	else if(p >= l + 2 * (n - l - 1)) printf("%d
    " , n);
    	else printf("%d
    " , l + (p - l) / 2 + 1);
    	return 0;
    }

     

  • 相关阅读:
    es6学习笔记
    vue.js项目目录结构说明
    js 数组操作总结
    js 数组去重方法
    HTTP协议三次握手过程
    MVC与MVVM模式对比
    谱面编辑器
    LL谱面分析和难度标定
    SLP的模块结构
    LL基本姿势
  • 原文地址:https://www.cnblogs.com/GXZlegend/p/6727210.html
Copyright © 2011-2022 走看看