Park Visit

Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 523    Accepted Submission(s): 236

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
 
Source
 
Recommend
liuyiding
 

题意:

一棵树,问从任意点出发,每次访问k个点走过的最少的边数

思路:我们可以这样考虑,假设我们走的起点为S,终点为T,那么路径S-T上的点我们必须都走到(因为是一棵树),那么如果路径S-T上的点大于或等于k,则我们只需要沿着路径一直走就行,所以最小长度为k-1,否则,我们一定是在路径上的一些点停下,然后转向其他分支然后再回来,此时才能满足一共走过k个点。假设从S到T的路径上一共有num个点,则最后我们要求的答案ans=num-1+?,这个?即为中间点(可以包括S和T)到别的分支再回来所要走的最小距离,因为每个分支互不影响,所以我们可以对每一个分支分开求,因为图为一棵树,所以我们即是求一棵子树从根节点到他的子节点中遍历x点再回来所要走的最短距离,我们可以有观察加数学归纳法证明这个值为2*x,即从一棵树的根结点往他的子树遍历x个点再回来的最小距离为2*x,所以?=2*(k-num),所以答案ans=num-1+(k-num)*2,要是这个值最小,则要使num最大,所以我们只要求得该树的直径即可,以下时代码,求树的直径是个很经典的问题了,

算法证明:(转)

树的直径(Diameter)是指树上的最长简单路。
直径的求法:两遍BFS (or DFS)
任选一点u为起点,对树进行BFS遍历,找出离u最远的点v
以v为起点,再进行BFS遍历,找出离v最远的点w。则v到w的路径长度即为树的直径
*简单证明
于是原问题可以在O(E)时间内求出

关键在于证明第一次遍历的正确性,也就是对于任意点u,距离它最远的点v一定是最长路的一端。
如果u在最长路上,那么v一定是最长路的一端。可以用反证法:假设v不是最长路的一端,则存在另一点v’使得(u→v’)是最长路的一部分,于是len(u→v’) > len(u→v)。但这与条件“v是距u最远的点”矛盾。
如果u不在最长路上,则u到其距最远点v的路与最长路一定有一交点c,且(c→v)与最长路的后半段重合(why?),即v一定是最长路的一端

因为是树是连通的,所以u必有一条路径c和最长路径L相交,len(c)>=1,L被分为两部分,一部分l1,一部分l2
假设第一次dfs过后,所求最长路径lu端不在L上,那么len(lu)>=len(c)+len(l1)(l1,l2对称,取l1或者l2都一样)
len(l2+c+lu)>len(l1+l2),矛盾.

#include<iostream>
#include<cstdio>
#include<cstring> using namespace std; const int VM=; struct Edge{
int to,nxt;
}edge[VM<<]; int n,m,cnt,head[VM];
int dis[VM]; void addedge(int cu,int cv){
edge[cnt].to=cv; edge[cnt].nxt=head[cu];
head[cu]=cnt++;
} void DFS(int u){
for(int i=head[u];i!=-;i=edge[i].nxt){
int v=edge[i].to;
if(dis[v]==-){
dis[v]=dis[u]+;
DFS(v);
}
}
} int main(){ //freopen("input.txt","r",stdin); int t;
scanf("%d",&t);
while(t--){
scanf("%d%d",&n,&m);
cnt=;
memset(head,-,sizeof(head));
int u,v;
for(int i=;i<n;i++){
scanf("%d%d",&u,&v);
addedge(u,v);
addedge(v,u);
}
memset(dis,-,sizeof(dis));
dis[]=;
DFS();
int len=;
for(int i=;i<=n;i++)
if(dis[i]>len){
len=dis[i];
u=i;
}
memset(dis,-,sizeof(dis));
dis[u]=;
DFS(u);
len=;
for(int i=;i<=n;i++)
if(dis[i]>len)
len=dis[i];
len++; //加一是因为刚开始的时候那点并不需要走1个距离,加一之后再与k比较
int k;
while(m--){
scanf("%d",&k);
if(len>=k)
printf("%d\n",k-);
else
printf("%d\n",(len-)+(k-len)*);
}
}
return ;
}

HDU 4607 Park Visit (树的最长链)的更多相关文章

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

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

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

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

  3. HDU 4607 Park Visit 树的最大直径

    题意: 莱克尔和她的朋友到公园玩,公园很大也很漂亮.公园包含n个景点通过n-1条边相连.克莱尔太累了,所以不能去参观所有点景点. 经过深思熟虑,她决定只访问其中的k个景点.她拿出地图发现所有景点的入口 ...

  4. [HDU4607]Park Visit(树上最长链)

    HDU#4607. Park Visit 题目描述 Claire and her little friend, ykwd, are travelling in Shevchenko's Park! T ...

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

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

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

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

  7. hdu 4607 Park Visit

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

  8. hdu 4607 Park Visit 求树的直径

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

  9. 题解报告:hdu 4607 Park Visit(最长链)

    Problem Description Claire and her little friend, ykwd, are travelling in Shevchenko's Park! The par ...

随机推荐

  1. 【转】深入理解line-height

    原文: http://www.cnblogs.com/dolphinX/p/3236686.html https://www.cnblogs.com/yangjie-space/p/4858132.h ...

  2. RAMPS1.4 3d打印控制板接线与测试1

    1.需要下载的软件 1.1 固件上传工具--Arduino IDE 这是上传固件的必备工具,有了这个软件让上传固件变的容易很多,插上USB,就可以轻松上传. 下载地址:windows版本:http:/ ...

  3. struct的初始化

    1.struct的初始化可以使用类似数组的方式,如下:struct Student{ int _Age; string _Name;};Student stu = {26,"Andy&quo ...

  4. Docker 容器入门

    1.1 容器简介 1.1.1 什么是 Linux 容器 Linux容器是与系统其他部分隔离开的一系列进程,从另一个镜像运行,并由该镜像提供支持进程所需的全部文件.容器提供的镜像包含了应用的所有依赖项, ...

  5. 解剖 CPU

    http://www.ruanyifeng.com/blog/2010/11/cpu_autopsy.html 有一个瑞典 Lund 大学物理学博士生,就真的这么干了,还把照片放到网上.我们知道,CP ...

  6. 保存登录plsql developer 的用户名和密码

    1 保存用户名 tools -> Preferences -> User Interface - Options 勾选 Autosave username . 保存 2 保存密码 tool ...

  7. 【高德地图SDK】如何实现轨迹平滑移动?

    很多人应该都有类似的经历,叫完车,想看看车离我还有多远距离?但手机屏幕上的车不是一动不动,就是一跳一跳的漂移. 目前市面上大多产品“轨迹平滑移动”做的并不好. 市面上只有快的打车和一号专车实现了平滑移 ...

  8. 老周发布 UWP 应用的隐私策略(通用)

    UWP 应用隐私策略 前注  本声明通用于老周所发布的所有 UWP 应用,下文简称“应用”.开发者全称:周家安,下文简称“老周”. 1.免责声明 您在使用应用过程中,请遵守<中华人民共和国宪法& ...

  9. (转)pip和easy_install使用方式

    easy_install 跟 pip 都是 Python 的套件管理程式,有了它們,在使用 Python 開發程式的時候會帶來不少方便. easy_install 和 pip 有什麼不一樣?據 pip ...

  10. ORA-01654错误

    问题现象: 测试库使用如下方式创建索引: create index IDX_ANA_OFFICE on ANA (OFFICE_CITY, OFFICE_NO)   tablespace IDX    ...