解题思路:

通过两次DFS求树的直径,第一次以随意点作为起点,找到距离该点距离最远的点,则能够证明这个点一定在树的直径上,然后以该点为起点进行DFS得到的最长路就是树的直径。

最后的询问,假设K <= D + 1则能够沿着直径走,距离为K  -  1, 假设K >= D + 1。则须要走直径旁边的分支,每訪问一个点距离为2(从直径到这个点,再返回到直径上)。

#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <cmath>
#include <vector>
#include <queue>
#define LL long long
using namespace std;
const int MAXN = 100000 + 10;
struct Edge
{
int to, next;
}edge[2 * MAXN];
int tot;
int head[MAXN];
int dis[MAXN];
int N, M;
void init()
{
tot = 0;
memset(head, -1, sizeof(head));
}
void addedge(int u, int v)
{
edge[tot].to = v;
edge[tot].next = head[u];
head[u] = tot++;
}
int dfs(int u, int pre = -1)
{
int ans = u;
for(int i=head[u];i!=-1;i=edge[i].next)
{
int v = edge[i].to;
if(v == pre) continue;
dis[v] = dis[u] + 1;
int dv = dfs(v, u);
if(dis[ans] < dis[dv]) ans = dv;
}
return ans;
}
int solve(int u)
{
dis[u] = 0;
u = dfs(u);
dis[u] = 0;
return dis[dfs(u)];
}
int main()
{
int T;
scanf("%d", &T);
while(T--)
{
scanf("%d%d", &N, &M);
init();
int u, v;
for(int i=1;i<N;i++)
{
scanf("%d%d", &u, &v);
addedge(u, v);
addedge(v, u);
}
int D = solve(1);
for(int i=1;i<=M;i++)
{
int K;
scanf("%d", &K);
if(K <= D + 1) cout << K - 1 << endl;
else cout << D + (K - D - 1) * 2 << endl;
}
}
return 0;
}

HDU 4607 Park visit (求树的直径)的更多相关文章

  1. hdu 4607 Park Visit 求树的直径

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

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

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

  3. hdu 4607 Park Visit

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

  4. Park Visit(树的直径)

    传送门 Park Visit Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)To ...

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

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

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

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

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

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

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

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

  9. F - Warm up - hdu 4612(缩点+求树的直径)

    题意:有一个无向连通图,现在问添加一条边后最少还有几个桥 分析:先把图缩点,然后重构图为一棵树,求出来树的直径即可,不过注意会有重边,构树的时候注意一下 *********************** ...

随机推荐

  1. python 10:len(list)(获取列表长度)以及负访问性

    bicycles = ['trek', 'cannondale', 'redline', 'specialized'] print(len(bicycles)) #获取某列表长度,即列表元素个数 pr ...

  2. Jmeter - 服务器性能检测

    在对系统做压力测试时,往往需要对服务的性能进行监控,包括CPU,Memory,IO,还有网络情况进行监控. Jemter有个一插件,能很好的支持这些性能监控.原理是服务器启动服务之后,测试机发起请求, ...

  3. wpf,vb,位图剪裁的方法

    ‘ 貌似WPF对GDI+不提供支持,要达到剪裁图像的方法,可以使用image.clip,’不过clip只是对图片的一个遮挡拦截效果,并不改变本身的图片资源.‘下面的代码提供了剪裁图片资源的方法. Di ...

  4. 【C++】cin、cout的效率比scanf和printf低的解决方法

    玩竞赛的同学应该发现了C++中直接调用cout.cin的效率要比printf和scanf的效率要低. 要解决这个问题,只需要在前面加上一句 std::ios::sync_with_stdio(fals ...

  5. [原创]Linux(CentOS)下安装mongodb

    和上一篇一样,装个这个踩了无数个坑…… 1.下载 wget http://fastdl.mongodb.org/linux/mongodb-linux-x86_64-rhel55-3.2.12.tgz ...

  6. Css小动画

    html页面: <!DOCTYPE html><html lang="en"><head> <meta charset="UTF ...

  7. 【MySQL】源码安装

    操作系统:Red Hat Enterprise Linux Server release 6.5 Mysql安装包:mysql-5.6.4-m7.tar.zip,下载地址:http://pan.bai ...

  8. 【oracle开发】wmsys.wm_concat介绍

    wmsys.wm_concat是一个聚合函数,其作用是将一列数据转换成一行,也就是我们常用的行专列,但是该函数是一个undocument函数,所以不推荐大家使用这个函数.因为在后续的版本中还提不提供这 ...

  9. ANN:DNN结构演进History—RNN

    前言: CNN在图像处理领域的极大成功源于CNN的二维递进映射结构,通过训练多层卷积核来进行特征提取函数训练,在二维图像的稀疏表达和语义关联分析方面有天生的结构优势.而涉及时序问题的逻辑序列分析-边长 ...

  10. 闲着无聊时写的一个调用天气 API 的小 Demo

    分为两个部分--调用以及实现,并且由于不想折腾,直接使用了 Console 来调用. 通过firefox直接调用 Main 入口,调用以及输出 调用部分没什么好说的,主要是针对 dynamic 类型的 ...