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

【思路】

访问K个城市的路线:

可以发现它由一条主线和若干支线构成,并且主线上的边只用访问一次,而支线上的边必须且只用访问两次。而题目给定的是一棵树,那么访问K的城市就必须且仅需要走K-1条边。总边数是固定的,我们只需要保证主线最长即可,所以就是在树中找最长链。

【找最长链】树形dp,dp[i]表示他的子树的最大深度。选一个树根开始访问,每次访问完根节点的子树都要找出子树中深度最深的两个,把他们加起来更新最长链长度。并且留下最深的深度+1当作根节点的深度。

#include
#include
#include
#include
#include
#include
#define MID(x,y) ((x+y)/2)
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
const int MAXN = 200005;
struct node{
int u, v;
int next;
}arc[MAXN];
int en, head[MAXN];
void init(){
en = 0;
mem(head, -1);
}
void insert(int u, int v){
arc[en].u = u;
arc[en].v = v;
arc[en].next = head[u];
head[u] = en ++;
}
int dp[MAXN];
int maxlen;
bool vis[MAXN];
void dfs(int u){
vis[u] = 1;
int max1 = 0, max2 = 0;
int num = 0;
for (int i = head[u]; i != -1; i = arc[i].next){
int v = arc[i].v;
if (!vis[v]){
num ++;
dfs(v);
if (dp[v] > max1){
max2 = max1;
max1 = dp[v];
}
else{
if (dp[v] > max2){
max2 = dp[v];
}
}
}
}
if (0 == num){
dp[u] = 0;
}
else{
if (num == 1)
maxlen = max(maxlen, max1+1);
else
maxlen = max(maxlen, max1+max2+2);
dp[u] = max1 + 1;
}
return ;
}
int main(){
//freopen("test.in", "r", stdin);
//freopen("test.out", "w", stdout);
int t;
scanf("%d", &t);
while(t --){
init();
int n, m;
scanf("%d %d", &n, &m);
for (int i = 0; i

HDU 4607 Park Visit (DP最长链)的更多相关文章

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

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

  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(树上最长链)

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

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

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

  5. hdu 4607 Park Visit 求树的直径

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

  6. hdu 4607 Park Visit

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

  7. hdu 4607 Park Visit (dfs)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4607 首先如果k小于等于直径长度,那么答案为k−1.如果k大于直径长度,设直径长度为r,那么答案为r− ...

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

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

  9. HDU 4607 Park visit (求树的直径)

    解题思路: 通过两次DFS求树的直径,第一次以随意点作为起点,找到距离该点距离最远的点,则能够证明这个点一定在树的直径上,然后以该点为起点进行DFS得到的最长路就是树的直径. 最后的询问,假设K &l ...

随机推荐

  1. javaZIP压缩文件

    问题描述: java ZIP压缩文件 问题解决:     说明:         防止创建压缩文件中中文乱码,需要导入的包:     (1)创建ZipOutputStream 注:     以上引用o ...

  2. 用hibernate自动创建mysql表,添加失败org.hibernate.exception.SQLGrammarException

    今天遇到了一个很坑人的问题,从昨晚一直搞到今天早上,终于发现了,先整理下: [背景]:利用hibernate自动给mysql创建一个表,然后为表里面添加一行记录,非常的简单(当然其中还涉及到sprin ...

  3. CentOS安装视频播放器SMPlayer

    首先下载rpmforg,下载对应的版本,就是对应CentOS版本,还有32位与64位也要对应上.地址如下: http://wiki.centos.org/AdditionalResources/Rep ...

  4. How does database indexing work?

    When data is stored on disk based storage devices, it is stored as blocks of data. These blocks are ...

  5. linux下获取时间差

    #include <sys/time.h> struct timeval tpstart,tpend;     float timeuse;     gettimeofday(&t ...

  6. POJ2151Check the difficulty of problems

    题意 : 举办一次比赛不容易,为了不让题目太难,举办方往往希望能够讲出的题目满足两点,1是所有的队伍都至少能够解出一个题目,2是冠军队至少能解出确定数量的题目,最后让你求的是每个队伍至少解出一道题并且 ...

  7. POJ1068Parencodings

    http://poj.org/problem?id=1068 这个题的话就是先把给出来的一串数字转化成括号,再把括号转化成要求的,最后输出就行了 #include<cstdio> #inc ...

  8. hdu 4412 Sky Soldiers DP

    动态规划,主要是用单调性求区间的最小期望. 代码如下: #include<iostream> #include<stdio.h> #include<algorithm&g ...

  9. lintcode 中等题: reverse linked list II 翻转链表II

    题目 翻转链表 II 翻转链表中第m个节点到第n个节点的部分 样例 给出链表1->2->3->4->5->null, m = 2 和n = 4,返回1->4-> ...

  10. java获取当前操作系统的信息

    java获取当前操作系统的信息 JavaOS虚拟机UnixEXT  从网上收集的一些关于java获取操作系统信息的方法,现在总结一下: 1获取本机的IP地址: private static Strin ...