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 of them. After consideration, she decides to visit only K spots among them. She takes out a map of the park, and luckily, finds that there're entrances at each feature spot! Claire wants to choose an entrance, and find a way of visit to minimize the distance she has to walk. For convenience, we can assume the length of all paths are 1.
Claire is too tired. Can you help her?

Input

An integer T(T≤20) will exist in the first line of input, indicating the number of test cases.
Each test case begins with two integers N and M(1≤N,M≤105), which respectively denotes the number of nodes and queries.
The following (N-1) lines, each with a pair of integers (u,v), describe the tree edges.
The following M lines, each with an integer K(1≤K≤N), describe the queries.
The nodes are labeled from 1 to N.

Output

For each query, output the minimum walking distance, one per line.

Sample Input

1
4 2
3 2
1 2
4 2
2
4

Sample Output

1
4
解题思路:看到这题肯定会想到用树的直径来求解,题目要求从某一点出发,访问连续k个点走过的最少边数。显然这时如果k个点都在树的直径上,那么经过的边数一定是最少的且为k-1,否则(即k>maxdist)就会经过树直径外的一些点(有k-maxdist个),并且剩下的这些点都被访问两次,而此时经过的边数最少为maxdist+(k-maxdist-1)*2。
AC代码一(499ms):一次dfs。
 #include<iostream>
#include<string.h>
#include<cstdio>
using namespace std;
const int maxn=1e5+;
struct EDGE{int to,next;}edge[maxn<<];
int t,n,m,k,x,y,cnt,res,maxdist,head[maxn];
void add_edge(int u,int v){
edge[cnt].to=v;
edge[cnt].next=head[u];
head[u]=cnt++;
}
int dfs(int u,int fa,int &maxdist){
int Dmax=,Dsec=;
for(int i=head[u];~i;i=edge[i].next){
int v=edge[i].to;
if(v^fa){
int nowd=dfs(v,u,maxdist)+;
if(nowd>Dmax)Dsec=Dmax,Dmax=nowd;
else if(nowd>Dsec)Dsec=nowd;
}
}
maxdist=max(maxdist,Dmax+Dsec);
return Dmax;
}
int main(){
while(~scanf("%d",&t)){
while(t--){
scanf("%d%d",&n,&m);
memset(head,-,sizeof(head));cnt=maxdist=;
while(--n){
scanf("%d%d",&x,&y);
add_edge(x,y);
add_edge(y,x);
}
dfs(,-,maxdist);
while(m--){
scanf("%d",&k);
if(k<=maxdist)printf("%d\n",k-);
else printf("%d\n",maxdist+(k-maxdist-)*);
}
}
}
return ;
}

AC代码二(546ms):两次bfs。

 #include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+;
struct EDGE{int to,next;}edge[maxn<<];
struct node{
int u,dep;
node(int x,int y):u(x),dep(y){}
};
int t,n,m,x,y,k,cnt,maxdep,maxvex,head[maxn];bool vis[maxn];
queue<node> que;
void add_edge(int u,int v){
edge[cnt].to=v;
edge[cnt].next=head[u];
head[u]=cnt++;
}
void bfs(int u,int dep,int &maxdep,int &maxvex){
while(!que.empty())que.pop();
memset(vis,false,sizeof(vis));
que.push(node(u,dep));vis[u]=true;
while(!que.empty()){
node nod=que.front();que.pop();
for(int i=head[nod.u];~i;i=edge[i].next){
int v=edge[i].to;
if(!vis[v]){
vis[v]=true;
que.push(node(v,nod.dep+));
}
}
if(maxdep<nod.dep)maxdep=nod.dep,maxvex=nod.u;
}
}
int main(){
while(~scanf("%d",&t)){
while(t--){
scanf("%d%d",&n,&m);
memset(head,-,sizeof(head));cnt=maxdep=;maxvex=;
while(--n){
scanf("%d%d",&x,&y);
add_edge(x,y);
add_edge(y,x);
}
bfs(,,maxdep,maxvex);maxdep=;
bfs(maxvex,,maxdep,maxvex);
while(m--){
scanf("%d",&k);
if(k<=maxdep)printf("%d\n",k-);
else printf("%d\n",maxdep+(k-maxdep-)*);
}
}
}
return ;
}

题解报告:hdu 4607 Park Visit(最长链)的更多相关文章

  1. HDU 4607 Park Visit (树的最长链)

    Park Visit Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  2. hdu 4607 Park Visit(树上最长链)

    求树上最长链:两遍搜索. 第一次从树上任意点开始,最远点必然是某一条最长链上的端点u. 第二次从u开始,最远点即该最长链的另一端点. 先在最长链上走,不足再去走支链. 把询问数m错打成n,狠狠wa了一 ...

  3. HDU 4607 Park Visit (DP最长链)

    [题目]题意:N个城市形成一棵树,相邻城市之间的距离是1,问访问K个城市的最短路程是多少,共有M次询问(1 <= N, M <= 100000, 1 <= K <= N). [ ...

  4. HDU 4607 Park Visit 两次DFS求树直径

    两次DFS求树直径方法见 这里. 这里的直径是指最长链包含的节点个数,而上一题是指最长链的路径权值之和,注意区分. K <= R: ans = K − 1; K > R:   ans = ...

  5. hdu 4607 Park Visit 求树的直径

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4607 题目大意:给你n个点,n-1条边,将图连成一棵生成树,问你从任意点为起点,走k(k<=n) ...

  6. hdu 4607 Park Visit

    http://acm.hdu.edu.cn/showproblem.php?pid=4607 先求树的直径 方法:两遍bfs ,任选一点 a  求到a点最远的一点b ,然后 求到b点最远点 c 这样 ...

  7. hdu 4607 Park Visit (dfs)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4607 首先如果k小于等于直径长度,那么答案为k−1.如果k大于直径长度,设直径长度为r,那么答案为r− ...

  8. HDU 4607 Park Visit(树的直径)

    题目大意:给定一棵树,让求出依次访问k个点的最小花费,每条边的权值都为1. 思路:如果能一直往下走不回来,那么这个路径肯定是最小的,这就取决于给定的k,但是怎么确定这个能一直走的长度呢,其实这个就是树 ...

  9. HDU 4607 Park visit (求树的直径)

    解题思路: 通过两次DFS求树的直径,第一次以随意点作为起点,找到距离该点距离最远的点,则能够证明这个点一定在树的直径上,然后以该点为起点进行DFS得到的最长路就是树的直径. 最后的询问,假设K &l ...

随机推荐

  1. Python调用C/Fortran混合的动态链接库--上篇

    内容描述: 在32位或64位的windows或GNU/Linux系统下利用Python的ctypes和numpy模块调用C/Fortran混合编程的有限元数值计算程序 操作系统及编译环境: 32bit ...

  2. A Practical Introduction to Blockchain with Python

    A Practical Introduction to Blockchain with Python // Adil Moujahid // Data Analytics and more http: ...

  3. Java虚拟机平台无关性

    jruby Java 虚拟机面试题全面解析(干货) - Yano_nankai的博客 - CSDN博客 http://m.blog.csdn.net/Yano_nankai/article/detai ...

  4. kaminari分页插件样式

    修改国际化文件,zh-cn views: pagination: first: "首页" last: "尾页" previous: "上一页" ...

  5. SQL Server 2012 安装图解教程(附sql2012下载地址)

    在安装微软最新数据库SQL Server 2012之前,编者先确定一下安装环境:Windonws 7 SP1,32位操作系统.CPU是2.1GHz赛扬双核T3500,内存2.93GB. sql2012 ...

  6. 常用bluetooth协议

    HFP: HFP(Hands-free Profile),让蓝牙设备可以控制电话,如接听.挂断.拒接.语音拨号等,拒接.语音拨号要视蓝牙耳机及电话是否支持. HSP: HSP 描述了 Bluetoot ...

  7. seafile看不见repo报500错误的解决方法

    环境 seafile-server-6.2.5 centos7.5 1804 现象 seafile服务器所在的VPS没动过,前一天seafile用还好好的,昨天客户端突然不能登录了,显示“服务器内部错 ...

  8. nyoj--86--找球号(一)(hash&&set&&二分)

    找球号(一) 时间限制:3000 ms  |  内存限制:65535 KB 难度:3 描述 在某一国度里流行着一种游戏.游戏规则为:在一堆球中,每个球上都有一个整数编号i(0<=i<=10 ...

  9. 创建app前的环境配置/AppIcon/启动图片

    1.真机调试http://blog.csdn.net/tht2009/article/details/48580569 2.创建app前的环境配置

  10. 理解Objective-C Runtime (五)协议与分类

    Objective-C中的分类允许我们通过给一个类添加方法来扩充它(但是通过category不能添加新的实例变量),并且我们不需要访问类中的代码就可以做到. Objective-C中的协议是普遍存在的 ...