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 ...
随机推荐
- SQL 连接操作 及 查询分析
- mysql的水平拆分和垂直拆分 (转)
http://www.cnblogs.com/sns007/p/5790838.html 1,水平分割: 例:QQ的登录表.假设QQ的用户有100亿,如果只有一张表,每个用户登录的时候数据库都要从这1 ...
- Linux反编译
转自:http://bbs.pediy.com/showthread.php?threadid=11315 一个简单的linux crackme的逆向前言 最不喜欢的就是写破解教程,酒后一时冲动 ...
- SQLSERVER 免费对比数据库结构和数据的工具支持:SQL Server 2012, SQL Server 2008 and SQL Server 2005
New xSQL Schema Compare - version 5 Compare the schemas of two SQL Server databases, review differen ...
- (转)最近一个项目中关于NGUI部分的总结(深度和drawCall)
在自己最近的一个项目中,软件的界面部分使用了NGUI来进行制作.在制作过程中,遇到了一些问题,也获取了一些经验,总结下来,作为日后的积累. 1.NGUI图集的使用. 此次是第一个自己正儿八经的制作完整 ...
- 模拟日历计算 poj1008
Maya Calendar Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 69932 Accepted: 21524 D ...
- IT行业简报 2014-2-8
1.微信在“我的银行卡”页面接入嘀嘀打车,三天内微信打车突破10万单,日均订单为70万,其中微信支付订单超过48万单2.三大运营商手机支付用户仅366.3万,与腾讯单月发展手机支付用户500万户相比, ...
- Global Web Index发布社交网络现状调查,Snapchat增速领跑移动端所有App,四分之一Facebook用户年龄在45岁以上【转载+整理】
原文地址 有次上班做公交,期间听到一个老太太说:"我加你微信啊--",还有一次去看老中医,并交换了电话,可当我回去后发现这个大夫竟然加了我微信--这些都令我有点吃惊,连60.70岁 ...
- WIN10系统 截图或者某些程序时屏幕会自动放大怎么办
右击这个应用程序,兼容性,以兼容模式运行,同时勾选高DPI设置时禁止显示缩放即可
- MySql【Insert Select Not Exist】判断记录再添加值的方案
INSERT INTO content ( detail, status, beginTime, endTime) SELECT @detail, , NULL, NULL FROM DUAL WHE ...