【题目】题意: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. 给定一个数组A[0,1,...,n-1],请构建一个数组B[0,1,...,n-1],其中B中的元素B[i]=A[0]*A[1]*...*A[i-1]*A[i+1]*...*A[n-1]。不能使用除法。

    // test14.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include<iostream> #include< ...

  2. css块级元素、行内元素

    说说对html页面元素的排列认识: html中所有元素从上到下排列,所以需要css来对其中的元素进行排序.调节样式,并用js为其添加交互效果. css的排序.定位是相对块级元素而言的,margin/p ...

  3. 2014 Multi-University Training Contest 8

    官方解题报告:http://blog.sina.com.cn/s/blog_a19ad7a10102uzj7.html Area of Mushroom http://acm.hdu.edu.cn/s ...

  4. 腾讯QQ企业邮箱在ruby on rails 框架中的mailer配置

    在编写ruby on rails程序时,我们可能会需要用到发送邮件的程序,如果使用gmail进行smtp发送一般问题不大,但很多企业使用的是腾讯QQ企业邮箱.使用该邮箱进行链接时出现各种错误,goog ...

  5. iscsi 操作备忘

    #查找iscsi节点 iscsiadm -m discovery -t st -p 192.168.20.225 #列出可用节点 iscsiadm -m node -T iqn.com.exapmle ...

  6. VisualSVN Server的windows 2003配置和使用方法(图文并茂)

    1.为什么要用VisualSVN Server,而不用Subversion? 回答: 因为如果直接使用Subversion,那么在Windows 系统上,要想让它随系统启动,就要封装SVN Serve ...

  7. maven 命令备忘

    1. 打包时 不执行测试 mvn package -Dmaven.test.skip=true

  8. sql查询数据库中所有表的记录条数,以及占用磁盘空间大小。

    SELECT TableName = obj.name, TotalRows = prt.rows, [SpaceUsed(KB)] = SUM(alloc.used_pages)* FROM sys ...

  9. ZOJ 2563 Long Dominoes(状压DP)

    给定一个m*n的方格子,要求用3*1的骨牌去覆盖,骨牌可以用横放或者竖放,问最终有多少种放置方式,将其铺满. 分析:由于最多30行,每行最多9列,所以可以按行来dp,设计每行的状态从而进行转移,考虑每 ...

  10. linux 查看局域网内ip

    $ sudo apt-get install nmap $ nmap -sP 192.168.1.1/24 windows 下直接arp -a就能看到.