HDU 4607 Park Visit (树的最长链)
Park Visit
Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 523 Accepted Submission(s): 236
Claire is too tired. Can you help her?
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.
4 2
3 2
1 2
4 2
2
4
4
题意:
一棵树,问从任意点出发,每次访问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 (树的最长链)的更多相关文章
- hdu 4607 Park Visit(树上最长链)
求树上最长链:两遍搜索. 第一次从树上任意点开始,最远点必然是某一条最长链上的端点u. 第二次从u开始,最远点即该最长链的另一端点. 先在最长链上走,不足再去走支链. 把询问数m错打成n,狠狠wa了一 ...
- HDU 4607 Park Visit(树的直径)
题目大意:给定一棵树,让求出依次访问k个点的最小花费,每条边的权值都为1. 思路:如果能一直往下走不回来,那么这个路径肯定是最小的,这就取决于给定的k,但是怎么确定这个能一直走的长度呢,其实这个就是树 ...
- HDU 4607 Park Visit 树的最大直径
题意: 莱克尔和她的朋友到公园玩,公园很大也很漂亮.公园包含n个景点通过n-1条边相连.克莱尔太累了,所以不能去参观所有点景点. 经过深思熟虑,她决定只访问其中的k个景点.她拿出地图发现所有景点的入口 ...
- [HDU4607]Park Visit(树上最长链)
HDU#4607. Park Visit 题目描述 Claire and her little friend, ykwd, are travelling in Shevchenko's Park! T ...
- HDU 4607 Park Visit 两次DFS求树直径
两次DFS求树直径方法见 这里. 这里的直径是指最长链包含的节点个数,而上一题是指最长链的路径权值之和,注意区分. K <= R: ans = K − 1; K > R: ans = ...
- HDU 4607 Park Visit (DP最长链)
[题目]题意:N个城市形成一棵树,相邻城市之间的距离是1,问访问K个城市的最短路程是多少,共有M次询问(1 <= N, M <= 100000, 1 <= K <= N). [ ...
- hdu 4607 Park Visit
http://acm.hdu.edu.cn/showproblem.php?pid=4607 先求树的直径 方法:两遍bfs ,任选一点 a 求到a点最远的一点b ,然后 求到b点最远点 c 这样 ...
- hdu 4607 Park Visit 求树的直径
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4607 题目大意:给你n个点,n-1条边,将图连成一棵生成树,问你从任意点为起点,走k(k<=n) ...
- 题解报告:hdu 4607 Park Visit(最长链)
Problem Description Claire and her little friend, ykwd, are travelling in Shevchenko's Park! The par ...
随机推荐
- 如何在原生工程中引入Cordova工程-for iOS 【转】
http://blog.csdn.net/e20914053/article/details/50170487 如今混合开发方兴未艾,有的项目可能一开始是原生开发的,后期需要加入混合开发,如将Cord ...
- 10gocm->session3->数据备份与恢复
这个实验考查我们当数据库出现问题宕机.数据丢失的情况下怎样挽回我们的损失,怎样在最短时间内恢复我们的数据库服务. RMAN规划 host target库 catalog库 ocm01 ocmdb ...
- Andriod NDK编译的时候无法使用math.h的函数。
编译NDK项目的时候,当用到sinf的时候,编译报错: 选中sinf函数,右键Go to declaration, 发现math.h的文件路径是: c:\ProgramData\Microsoft\A ...
- How to center body on a page?
[提问] I'm trying to center the body element on my HTML page. Basically, in the CSS I set the body e ...
- ZooKeeper启动报错 JAVA_HOME is incorrectly set
解决办法:在zkEnv.cmd文件中直接写死调用的jdk路径 set JAVA_HOME="D:\Program Files\Java7\jdk1.7.0_51" if not e ...
- Spring 集成 redistemplate
jar包 <version.clients.jedis>2.7.2</version.clients.jedis><version.data.redis>1.6.2 ...
- 论文阅读:Memory Networks
一.论文所解决的问题 实现长期记忆(大量的记忆),而且实现怎样从长期记忆中读取和写入,此外还增加了推理功能 为什么长期记忆非常重要:由于传统的RNN连复制任务都不行,LSTM预计也够玄乎. 在QA问题 ...
- 推荐一款jQuery ColorPicked 颜色拾取器插件
先看实现的效果图, 本文底部有完整demo 不想看我墨迹的可以跳过了^_^. 官网地址:http://www.eyecon.ro/colorpicker/#about 代码SVN 地址:https:/ ...
- Python连接MySQL的实例代码
Python连接MySQL的实例代码 MySQLdb下载地址:http://sourceforge.net/projects/mysql-python/ 下载解压缩后放到%Python_HOME% ...
- Spring Integration概述
1. Spring Integration概述 1.1 背景 Spring框架的一个重要主题是控制反转.从广义上来说,Spring处理其上下文中管理的组件的职责.只要组件减轻了职责,它们同 ...