解题思路:

通过两次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 36 死锁现象和递归锁、信号量、Event事件、线程queue

    一:死锁现象和递归锁 所谓死锁: 是指两个或两个以上的进程或线程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去.此时称系统处于死锁状态或系统产生了死锁,这些永远 ...

  2. MSSQL:账号无法删除方案

    1.查询 EXEC sp_who 'WIN-GBKBCVTG4CN\Administrator' 返回一个表格,其中有列[spid] 2.删除 kill spid

  3. 5.17 Quartz笔记

    有用到构建者模式: builder---JobDetail相当于需要构建者构建出来的一个配件:JobDetail为Job实例提供了许多设置属性,以及JobDetaMap成员变量属性,它用来存储特定Jo ...

  4. bootstrap 图片 图标

    一.图片 1.响应式图片:<img src="  " class="responsive"> 2.圆角图片:<img src="  ...

  5. Unity引擎GUI之Text

    Text 文本 要显示的字符串. Font 字体 Font Style 加粗与倾斜 Font Size 字体大小 Line Spacing 行距,文本行之间的间距 Rich Text 勾选后,想要单独 ...

  6. 阶乘问题-----sum随变量改变而改变

  7. mongoose 操作 mongodb 笔记 (自己的笔记,自己看的)

    mongodb下载/安装 mongoose   npm install --save mongoose mongoose 数据库连接 const mongoose = require('mongoos ...

  8. GrepWin:Win7下的文本替换工具

    工作环境退回到Win7之后,内容查找功能非常不给力,推荐一个文本内容查找工具grepWin. Win7下的文本查找/替换工具: grepWin

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

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

  10. 移动APP 微信支付完整过程(wxPay 方案一)

    apicloud.weixinpay官方提供了两种方案. 本模块封装了两套支付方案: 方案一:开发者通过 getOrderId.payOrder 自己处理签名过程(微信开放平台建议把 getOrder ...