HDU4607 Park Visit

问题链接HDU4607 Park Visit

问题简述:莱克尔和她的朋友到公园玩,公园很大也很漂亮。公园包含n个景点通过n-1条边相连。克莱尔太累了,所以不能去参观所有点景点。经过深思熟虑,她决定只访问其中的k个景点。她拿出地图发现所有景点的入口都很特殊。所以她想选择一个入口,并找到一条最短的路来参观k个景点。假设景点之间的距离为1。

输入数据:先输入测试用例数t,每个测试用例数据包括N和M,N为节点数,M为需要查询的上述的k(参观M个景点)。

输出数据:对于各个M,输出需要走的距离。

问题分析:n个节点n-1条边构成无向无环树。该问题就是求树直径,树直径即树上最长路径。假设树直径包含m个节点(直径为m-1),若k<=m,则答案为k-1,否则答案为m + (k-m-1)*2。

程序说明:函数dfs()用于计算树直径经过的节点数。其他都是套路。

AC的C++语言程序如下:

/* HDU4607 Park Visit */

#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>

using namespace std;

const int MAXN = 100000;
vector<int>tree[MAXN+1];
bool visit[MAXN];

int maxlen;         // 树的最大直径
// DFS求最大树的直径
int dfs(int u)
{
   visit[u] = true;
   int max=0, lastmax=0, size;

   size = tree[u].size();
   for(int i=0; i<size; i++){
        if(visit[tree[u][i]])
            continue;
        int temp = dfs(tree[u][i]);
        if( temp + 1  > max){
            lastmax = max ;
            max = temp + 1;
        }else if( temp + 1 > lastmax)
            lastmax = temp + 1;
        if( maxlen < max + lastmax)
            maxlen = max + lastmax;
   }

   return max;
}

int main(void)
{
    int t, n, m, u, v, k;

    scanf("%d", &t);
    while(t--) {
        scanf("%d%d", &n, &m);

        for(int i=1; i<=n; i++)
            tree[i].clear();

        for(int i=1; i<n; i++) {
            scanf("%d%d", &u, &v);
            tree[u].push_back(v);
            tree[v].push_back(u);
        }

        memset(visit, false, sizeof(visit));
        maxlen = 0;
        dfs(1);

        while(m--) {
            scanf("%d", &k);
            if(k <= maxlen)
                printf("%d\n", k-1);
            else
                printf("%d\n", maxlen + (k-maxlen-1)*2);
        }
    }

    return 0;
}
时间: 2024-08-06 03:41:46

HDU4607 Park Visit的相关文章

HDU4607 Park Visit(解法二)

问题链接:HDU4607 Park Visit. 题意简述:莱克尔和她的朋友到公园玩,公园很大也很漂亮.公园包含n个景点通过n-1条边相连.克莱尔太累了,所以不能去参观所有点景点.经过深思熟虑,她决定只访问其中的k个景点.她拿出地图发现所有景点的入口都很特殊.所以她想选择一个入口,并找到一条最短的路来参观k个景点.假设景点之间的距离为1. 输入数据:先输入测试用例数t,每个测试用例数据包括N和M,N为节点数,M为需要查询的上述的k(参观M个景点). 输出数据:对于各个M,输出需要走的距离. 问题

hdu4607 Park Visit(树的直径)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4607 题意:给定一棵树,从树中的任意选一个顶点出发,遍历K个点的最短距离是多少?(每条边的长度为1) 代码: #include<iostream> #include<cstdio> #include<algorithm> #include<cstring> using namespace std; #define ll long long const int m

Park Visit

hdu4607:http://acm.hdu.edu.cn/showproblem.php?pid=4607 题意:给你一棵树,树上每条边的权值是1,然后然你选择m个点,求遍历m个点的最小花费. 题解:这一题要用到树的性质.首先可以想到的是第一次肯定要选择一条最长的路径,也就是树的直径.至于其余的点怎么考虑呢?画个图可以知道,剩余的点的所产生的花费就是剩余点数的两倍,所以本题的关键就是求树的直径.求树的直径,是有方式的,就是两遍DFS,第一遍DFS找到一个当前点的最远的点,然后从这个最远的点开始

HDU 4607 Park Visit 求树的直径

Park Visit Problem Description Claire and her little friend, ykwd, are travelling in Shevchenko's Park! The park is beautiful - but large, indeed. N feature spots in the park are connected by exactly (N-1) undirected paths, and Claire is too tired to

Park Visit(树的直径)

传送门 Park Visit Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 3721    Accepted Submission(s): 1667 Problem Description Claire and her little friend, ykwd, are travelling in Shevchenko's Park! T

hdu 4607 Park Visit(树的直径)

Park Visit Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2506    Accepted Submission(s): 1128 Problem Description Claire and her little friend, ykwd, are travelling in Shevchenko's Park! The

HDU 4607 Park Visit

Problem Description Claire and her little friend, ykwd, are travelling in Shevchenko's Park! The park is beautiful - but large, indeed. N feature spots in the park are connected by exactly (N-1) undirected paths, and Claire is too tired to visit all

题解报告:hdu 4607 Park Visit(最长路+规律)

Problem Description Claire and her little friend, ykwd, are travelling in Shevchenko's Park! The park is beautiful - but large, indeed. N feature spots in the park are connected by exactly (N-1) undirected paths, and Claire is too tired to visit all

HDU 4607 Park Visit(树的直径)

题目大意:给定一棵树,让求出依次访问k个点的最小花费,每条边的权值都为1. 思路:如果能一直往下走不回来,那么这个路径肯定是最小的,这就取决于给定的k,但是怎么确定这个能一直走的长度呢,其实这个就是树的直径,也叫作最长简单路径.找出来这个直径之后,只需和k比较一下就能确定走多少步.设直径为maxx, 如果maxx + 1== k的话,说明刚好不用回来走完最长的这个路,所以当k小于等于maxx + 1的时候就是k-1,当k大于maxx + 1的时候,除了要走完不用回来的路,肯定还要走那些用回来的,