HDU4607(求树中的最长链)
来源:互联网 发布:去除美图秀秀的软件 编辑:程序博客网 时间:2024/06/05 18:32
题目:Park Visit
题意:给定一棵树,从树中的任意选一个顶点出发,遍历K个点的最短距离是多少?(每条边的长度为1)
解析:就是求树的最长链,假设求出的树的最长链所包含的点数为m,那么如果K<=m,那么答案就是K-1,否则就是(K-m)*2+m-1
找树中最长链方法是:
可以通过经典的O(n)的算法求出树的直径。做法是从任意一点开始DFS或者BFS一次求出一个最远的点,这是直径的一个端点;
再从这个最远点开始再次DFS或者BFS,再找到的最远点就是直径的另外一个端点。
#include <iostream>#include <string.h>#include <stdio.h>using namespace std;const int N=200010;int head[N],to[N],next[N],w[N];int dis[N],que[N];bool vis[N];int edge,m,n;void init(){ memset(head,-1,sizeof(head)); edge=0;}void add(int u,int v,int c){ to[edge]=v,w[edge]=c,next[edge]=head[u],head[u]=edge++; to[edge]=u,w[edge]=c,next[edge]=head[v],head[v]=edge++;}void bfs(int s){ memset(vis,0,sizeof(vis)); memset(dis,0,sizeof(dis)); int l,r,v,u; l=r=0; vis[s]=1; dis[s]=0; que[r++]=s; while(r>l) { u=que[l++]; for(int i=head[u]; ~i; i=next[i]) { if(!vis[v=to[i]]) { vis[v]=1; dis[v]=dis[u]+w[i]; que[r++]=v; } } }}int treediameter(int s){ int u,maxl; bfs(s); maxl=0,u=s; for(int i=1; i<=n; i++) if(dis[i]>maxl) u=i,maxl=dis[i]; bfs(u); maxl=0; for(int i=1; i<=n; i++) if(dis[i]>maxl) maxl=dis[i]; return maxl;}int main(){ int u,v,d=1,t,i,j,x; scanf("%d",&t); while(t--) { init(); scanf("%d%d",&n,&m); for(i=1;i<=n-1;i++) { scanf("%d%d",&u,&v); add(u,v,1); } int ans=treediameter(1); ans++; while(m--) { scanf("%d",&x); if(x<=ans) printf("%d\n",x-1); else printf("%d\n",(x-ans)*2+ans-1); } } return 0;}
- HDU4607(求树中的最长链)
- HDU4607(求树的直径)
- hdu4607 (求树的直径)
- hdu4607双dfs求树的直径+公式
- HDU4607 树的直径
- hdu4607 树的直径
- hdu4607
- hdu4607
- hdu4607
- hdu4607
- hdu4607 Park Visit (树直径)
- HDU4607(最大直径 树DP)
- hdu4607(树的直径+公式)
- 求数组中的最长平台
- 求字符串中的最长回文
- [hihocoder#1050 : 树中的最长路] 两种树形DP方法求树的最长路
- 求二叉树中的第一条最长路径长度,并输出最长路径上的节点
- hdu4607—Park Visit(树的直径)
- 关于C语言中继承和多态的实现
- 基础知识如何扎实都不为过
- 2037 ——今年暑假不AC
- LoadIcon
- c——文件读写
- HDU4607(求树中的最长链)
- 2036 ——改革春风吹满地
- 分割文件合并
- shell编程
- 黑马程序员 Java 语言基础上
- test
- 用Ant实现Java项目的自动构建和部署
- 2035 ——人见人爱A^B
- 北京合租谁伤的起