HDU 4607 Park Visit 两次DFS求树直径
两次DFS求树直径方法见 这里。
这里的直径是指最长链包含的节点个数,而上一题是指最长链的路径权值之和,注意区分。
K <= R: ans = K − 1;
K > R: ans = R − 1 + ( K − R ) ∗ 2;
1 #include <cstdio> 2 #include <cstring> 3 #include <cstdlib> 4 #include <algorithm> 5 6 using namespace std; 7 8 const int MAXN = 100010; 9 10 struct node 11 { 12 int v; 13 int next; 14 }; 15 16 int N, Q, EdgeN; 17 int head[MAXN]; 18 int best[MAXN]; 19 int dp[MAXN][3]; 20 node D[ MAXN << 1 ]; 21 bool vis[MAXN]; 22 23 void AddEdge( int u, int v ) 24 { 25 D[EdgeN].v = v; 26 D[EdgeN].next = head[u]; 27 head[u] = EdgeN++; 28 return; 29 } 30 31 void DFS1( int u ) 32 { 33 vis[u] = true; 34 for ( int i = head[u]; i != -1; i = D[i].next ) 35 { 36 int v = D[i].v; 37 int w = 1; 38 if ( !vis[v] ) 39 { 40 DFS1( v ); 41 if ( dp[v][0] + w > dp[u][0] ) 42 { 43 dp[u][1] = dp[u][0]; 44 dp[u][0] = dp[v][0] + w; 45 best[u] = v; 46 } 47 else if ( dp[v][0] + w > dp[u][1] ) 48 dp[u][1] = dp[v][0] + w; 49 } 50 } 51 return; 52 } 53 54 void DFS2( int u ) 55 { 56 vis[u] = true; 57 for ( int i = head[u]; i != -1; i = D[i].next ) 58 { 59 int fa = D[i].v; 60 int w = 1; 61 if ( !vis[fa] ) 62 { 63 dp[fa][2] = dp[u][2] + w; 64 if ( fa == best[u] ) 65 dp[fa][2] = max( dp[fa][2], dp[u][1] + w ); 66 else dp[fa][2] = max( dp[fa][2], dp[u][0] + w ); 67 DFS2( fa ); 68 } 69 } 70 return; 71 } 72 73 int main() 74 { 75 int T; 76 scanf( "%d", &T ); 77 while ( T-- ) 78 { 79 scanf( "%d%d", &N, &Q ); 80 EdgeN = 0; 81 memset( head, -1, sizeof(head) ); 82 for ( int i = 1; i < N; ++i ) 83 { 84 int u, v; 85 scanf( "%d%d", &u, &v ); 86 AddEdge( u, v ); 87 AddEdge( v, u ); 88 } 89 90 memset( dp, 0, sizeof(dp) ); 91 memset( vis, false, sizeof(bool) * (N + 1) ); 92 DFS1( 1 ); 93 memset( vis, false, sizeof(bool) * (N + 1) ); 94 DFS2( 1 ); 95 96 int maxx = 0; 97 for ( int i = 1; i <= N; ++i ) 98 maxx = max( maxx, max( dp[i][0], dp[i][2] ) ); 99 ++maxx; 100 101 while ( Q-- ) 102 { 103 int K; 104 scanf( "%d", &K ); 105 if ( maxx >= K ) 106 printf( "%d\n", K - 1 ); 107 else printf( "%d\n", maxx - 1 + ( K - maxx ) * 2 ); 108 } 109 } 110 return 0; 111 }
转载于:https://www.cnblogs.com/GBRgbr/p/3220455.html
HDU 4607 Park Visit 两次DFS求树直径相关推荐
- hdu 4607 Park Visit 求树的直径
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4607 Claire and her little friend, ykwd, are travelli ...
- HDU - 4607 Park Visit (树的直径)
http://acm.hdu.edu.cn/showproblem.php?pid=4607 题意 一颗n个顶点的树,现在只想访问其中k个,问最短路径长度为多少. 分析 首先,最短的路径当然是一条链. ...
- HDU 4607 Park Visit(树的直径)
题目大意:给定一棵树,让求出依次访问k个点的最小花费,每条边的权值都为1. 思路:如果能一直往下走不回来,那么这个路径肯定是最小的,这就取决于给定的k,但是怎么确定这个能一直走的长度呢,其实这个就是树 ...
- hdu 4607 Park Visit(树上最长链)
求树上最长链:两遍搜索. 第一次从树上任意点开始,最远点必然是某一条最长链上的端点u. 第二次从u开始,最远点即该最长链的另一端点. 先在最长链上走,不足再去走支链. 把询问数m错打成n,狠狠wa了一 ...
- HDU 4607 Park Visit HDU暑期多校1
10W个点的一棵树,边权为1 求访问K个点要走过的最小路程 BFS求出一条最长路以后,我们可以YY出其他的边都要重复走两次 树上的最长路可以从任意一点开始BFS求出这点的最大距离,再把终点设置为起点再 ...
- PAT甲级1021 Deepest Root :[C++题解]树的最大深度、并查集、dfs求树的深度
文章目录 题目分析 题目链接 题目分析 分析: 考察知识点:并查集.dfs.树的深度 给定n个结点,n-1条边,只要能保证只有1个连通分量,就是一棵树.否则的话就不是树,它是不连通的. 用并查集来看是 ...
- acwing 1078. 旅游规划(求树直径上的点)
题目链接 题意:给一个树,可能直径不唯一,求所有直径上的所有的点 思路: 这题刚开始以为可以两次bfs,第二次bfs的时候记录前驱暴力求解,结果tle了 = =.. 正确解法是,先用dp求直径,然后从 ...
- PAT甲级1053 Path of Equal Weight (30分) :[C++题解]dfs求树的路径长度、邻接表
文章目录 题目分析 题目链接 题目分析 输入样例: 20 9 24 10 2 4 3 5 10 2 18 9 7 2 2 1 3 12 1 8 6 2 2 00 4 01 02 03 04 02 1 ...
- 求树的直径的两种方法
树的直径 树型dp求树的直径 优缺点: 优点为可以处理边权为负的情况,但不易得到直径的路径(指树的直径经过什么点). 代码模板: #include<bits/stdc++.h> using ...
最新文章
- LoadRunner之二“集合点”
- 经典网络AlexNet介绍
- 人工智能 MIT 博士系列讲课
- python | gtts 将文字转化为语音内容
- Java中print、printf、println的区别 详解
- numpy.negative详解
- Deeplab 在Qt Creator下编译报错undefined reference to Mat_xxx
- scanf()的使用
- mac下查看redis安装路径_干货!win10环境下Redis安装、启动教程
- Cas单点登录配置数据查询用户
- shmget出现Invalid argument错误
- 酷狗显示服务器失败怎么回事,酷狗音乐上传音乐失败怎么回事
- RS编码过程通俗理解
- matlab设置等高线标注字体大小,matlab设置图中字体和线条大小等(转)
- 奥维地图从服务器获取信息超时,2021奥维地图不能用了原因及解决办法
- MOSS入门介绍 和 概念介绍
- 2549. 删除他们! 解题报告
- 【产品经理】AARRR模型
- 微信扫码签到系统asp源码2.0示例
- Unity 设置程序在后台运行