HDU#4607. Park Visit


题目描述


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?
 

输入格式


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.
 

输出格式


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

样例输入输出


输入


1 4 2 3 2 1 2 4 2 2 4

  

输出


1 4

  

题意:


给定一棵树,从树中的任意选一个顶点出发,遍历K个点的最短距离是多少?(每条边的长度为1)
 

分析:


 
很自然的联想到求一遍最长链。设最长链长度为len
如果K < len + 1,那么答案就为K - 1,因为只需在最长链上走就行了。
如果K > len + 1;那么肯定不能不重复的遍历完K个点,一定有些点会重复遍历。这样就有些点的子树需要重复遍历,我们肯定不会去选取最长链重复遍历。
就是最长链上的点为根,不包含最长链的子树重复遍历。那么答案就变成了 len + (K - len - 1) * 2
 
 

树上最长链:


 
 求树上最长链的方法是用dp来求的。
f1表示从一个点子树里的最长链,f2表示一个点子树里的次长链。维护一下,然后答案为每个点f1 + f2的之中的最大值

int dfs(int u,int pre){
for(int i = head[u];i;i = edge[i].next){
int v = edge[i].to;
if(v == pre)continue;
dfs(v,u);
if(f1[u] < f1[v] + edge[i].dis)
{
f2[u] = f1[u];
f1[u] = f1[v] + edge[i].dis;
}
else f2[u] = max(f2[u],f1[v] + edge[i].dis);
}
ans = max(ans,f1[u] + f2[u]);
return ans;
}

贴上AC代码:


# include <iostream>
# include <cstdio>
# include <cstring>
# include <algorithm>
using namespace std;
const int N = 1e5 + ;
const int M = 2e5 + ;
const int INF = 0x3f3f3f3f;
int n,m,cnt,head[N];
int read()
{
int ans=,f=;
char i=getchar();
while(i<''||i>''){if(i=='-')f=-;i=getchar();}
while(i>=''&&i<=''){ans=ans*+i-'';i=getchar();}
return ans*f;
}
struct Edge{
int to,next;
int dis;
}edge[M];
void AddEdge(int u,int v,int res){
Edge E1 = {v,head[u],res};
edge[++cnt] = E1;head[u] = cnt;
Edge E2 = {u,head[v],res};
edge[++cnt] = E2;head[v] = cnt;
}
long long f1[N],f2[N],ans;
int dfs(int u,int pre){
for(int i = head[u];i;i = edge[i].next){
int v = edge[i].to;
if(v == pre)continue;
dfs(v,u);
if(f1[u] < f1[v] + edge[i].dis)
{
f2[u] = f1[u];
f1[u] = f1[v] + edge[i].dis;
}
else f2[u] = max(f2[u],f1[v] + edge[i].dis);
}
ans = max(ans,f1[u] + f2[u]);
return ans;
}
void Init(){
memset(head,,sizeof head);
memset(f1,,sizeof f1);
memset(f2,,sizeof f2);
cnt = ans = ;
}
void Getmap(){
Init();
n = read(), m = read();
int x,y,z;
for(int i = ;i < n;i++){
x = read();y = read();
AddEdge(x,y,);
}
dfs(,-);
ans += ;
for(int i = ;i <= m;i++){
x = read();
if(x <= ans)printf("%d\n",x - );
else printf("%d\n",ans - + (x - ans) * );
}
}
int main(){
int T;
T = read();
while(T--)
Getmap();
return ;
}
  

[HDU4607]Park Visit(树上最长链)的更多相关文章

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

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

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

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

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

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

  4. hdu 4612 Warm up(缩点+树上最长链)

    本来就是自己负责图论,结果水了= = 题目其实很裸,就是求桥的数量,只是要新加上一条边罢了.做法:先缩点.再在树上搜最长链(第一场多校的hdu 4607Park Visit就考了最长链,小样,套个马甲 ...

  5. HDU4607(求树中的最长链)

    题目:Park Visit 题意:给定一棵树,从树中的任意选一个顶点出发,遍历K个点的最短距离是多少?(每条边的长度为1) 解析:就是求树的最长链,假设求出的树的最长链所包含的点数为m,那么如果K&l ...

  6. 树上最长链 Farthest Nodes in a Tree LightOJ - 1094 && [ZJOI2007]捉迷藏 && 最长链

    树上最远点对(树的直径) 做法1:树形dp 最长路一定是经过树上的某一个节点的. 因此: an1[i],an2[i]分别表示一个点向下的最长链和次长链,次长链不存在就设为0:这两者很容易求 an3[i ...

  7. CF1009F Dominant Indices(树上DSU/长链剖分)

    题目大意: 就是给你一棵以1为根的树,询问每一个节点的子树内节点数最多的深度(相对于这个子树根而言)若有多解,输出最小的. 解题思路: 这道题用树链剖分,两种思路: 1.树上DSU 首先想一下最暴力的 ...

  8. hdu4607 Park Visit(树的直径)

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

  9. HDU-4607 Park Visit bfs | DP | dfs

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4607 首先考虑找一条最长链长度k,如果m<=k+1,那么答案就是m.如果m>k+1,那么最 ...

随机推荐

  1. 自欺欺人的使用 NSTimer 销毁

    自欺欺人的使用 NSTimer 销毁 Demo地址 1.NSTimer是要加到runloop中才会起作用. 常见的创建timer方式 // 第一种方式 @property (nonatomic , s ...

  2. pocket API学习笔记

    最近安装了pocket离线阅读软件. 为了收藏需要的URL,每次都要打开浏览器.然后按google工具条上的pocket+. 网页多的时候,这个过程就非常缓慢. 根据pocket网站的API介绍,我可 ...

  3. SEO 第十章

    SEO第十章 本次课目标: 1.  站外优化方案计划 2.  常见的SEO作弊手段(黑帽) 3.  百度站长平台的使用 4.  网站流量提升和转化率提升 一.站外优化方案计划 友情链接 权重相当.行业 ...

  4. (译文)IOS block编程指南 4 声明和创建blocks

    Declaring and Creating Blocks (声明和创建blocks) Declaring a Block Reference (声明一个block引用) Block variable ...

  5. 技术抄录_Java高级架构师教程

    1.B2C商城项目实战     2.高性能架构专题     3.架构筑基与开源框架解析专题     4.团队协作开发专题     5.微服务架构专题     6.设计模式     附上[架构资料]   ...

  6. C++ 类中的static成员的初始化和特点

    C++ 类中的static成员的初始化和特点 #include <iostream> using namespace std; class Test { public: Test() : ...

  7. 2012 noip提高 Vigenère 密码

    P1079 Vigenère 密码 题目描述 16 世纪法国外交家 Blaise de VigenèreBlaisedeVigene`re 设计了一种多表密码加密算法―― VigenèreVigene ...

  8. 【转载】Sql语句用left join 解决多表关联问题(关联套关联,例子和源码)

    csdn中高手帮我给解决了,其实就是别名,给自己上了一堂别名的课,所谓别人是高手,其实就是自己是菜鸟吧! 表1:------------------------------ [人事表]     表名: ...

  9. Oracle 10g R2 Transparent Data Encryption 透明数据加密

    Oracle 10g R2 Transparent Data Encryption 透明数据加密 本章介绍如何使用透明数据加密来保护Oracle数据库中的敏感数据,该功能使您可以加密数据库列并管理加密 ...

  10. 深入Linux内核架构——进程管理和调度(下)

    五.调度器的实现 调度器的任务是在程序之间共享CPU时间,创造并行执行的错觉.该任务可分为调度策略和上下文切换两个不同部分. 1.概观 暂时不考虑实时进程,只考虑CFS调度器.经典的调度器对系统中的进 ...