当时比赛的时候我们找出来只要求出树的最长的边的节点数ans,如果要访问点的个数n小于ans距离直接就是n-1

如果大于的话就是(n-ans)*2+ans-1,当时求树的直径难倒我们了,都不会树形dp

选一个点当根每次求出一点到子节点的最大距离和次大距离,两个的和最大的就是树的直径

还在网上看到一种方法,任意一点广搜达到最远点max,再从max广搜,到达最远点就是树的直径

自己想了想这种方法:如果中间有点有分支的话,那么这点的最大分支一定是到max的

但是它的次大分支就不一定是到起点的,所以从max搜的话肯定是到这点的次大分支,就是直径了

#include<stdio.h>
#include<string.h>
#define N 100001
int head[N],num,ins[N],n;
struct edge
{
int ed,next;
}E[N*2];
void addedge(int x,int y)
{
E[num].ed=y;
E[num].next=head[x];
head[x]=num++;
}
int dis;
int dist(int u)
{
ins[u]=1;
int max=0,mmax=0;
for(int i=head[u];i!=-1;i=E[i].next)
{
int v=E[i].ed;
if(ins[v]==1)continue;
int temp=dist(v);
if(temp>mmax)
{
max=mmax;
mmax=temp;
}
else if(temp>max)
{
max=temp;
}
}
if(dis<(mmax+max+1))
dis=mmax+max+1;
return mmax+1;
}
int main()
{
int i,m,x,y,t;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
memset(head,-1,sizeof(head));
num=0;
for(i=0;i<n-1;i++)
{
scanf("%d%d",&x,&y);
addedge(x,y);
addedge(y,x);
}
memset(ins,0,sizeof(ins));
dis=0;
dist(1);
for(i=1;i<=m;i++)
{
scanf("%d",&x);
if(x<=dis)
printf("%d\n",x-1);
else printf("%d\n",dis+(x-dis)*2-1);
}
}
return 0;
}
#include<stdio.h>
#include<queue>
#include<string.h>
#define N 100001
using namespace std;
int head[N],num,vis[N],n;
struct edge
{
int ed,next;
}E[N*2];
struct node
{
int x,w;
}cur,next;
void addedge(int x,int y)
{
E[num].ed=y;
E[num].next=head[x];
head[x]=num++;
}
int dist()
{
int i,v;
memset(vis,0,sizeof(vis));
queue<node>Q1,Q2;
cur.x=1;
Q1.push(cur);
while(!Q1.empty())
{
cur=Q1.front();
Q1.pop();
vis[cur.x]=1;
for(i=head[cur.x];i!=-1;i=E[i].next)
{
next.x=v=E[i].ed;
if(vis[v]==0)
Q1.push(next);
}
}
cur.w=1;
Q2.push(cur);//广搜最后出来的点一点是最远点
memset(vis,0,sizeof(vis));
while(!Q2.empty())
{
cur=Q2.front();
Q2.pop();
vis[cur.x]=1;
for(i=head[cur.x];i!=-1;i=E[i].next)
{
next.x=v=E[i].ed;
next.w=cur.w+1;
if(vis[v]==0)
Q2.push(next);
}
}
return cur.w;
}
int main()
{
int i,m,x,y,t;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
memset(head,-1,sizeof(head));
num=0;
for(i=0;i<n-1;i++)
{
scanf("%d%d",&x,&y);
addedge(x,y);
addedge(y,x);
}
int dis=dist();
for(i=1;i<=m;i++)
{
scanf("%d",&x);
if(x<=dis)
printf("%d\n",x-1);
else printf("%d\n",dis+(x-dis)*2-1);
}
}
return 0;
}

hdu 4607 (树形DP)的更多相关文章

  1. hdu 4607 树形dp 树的直径

    题目大意:给你n个点,n-1条边,将图连成一棵生成树,问你从任意点为起点,走k(k<=n)个点,至少需要走多少距离(每条边的距离是1): 思路:树形dp求树的直径r: a:若k<=r+1 ...

  2. hdu 4123 树形DP+RMQ

    http://acm.hdu.edu.cn/showproblem.php? pid=4123 Problem Description Bob wants to hold a race to enco ...

  3. HDU 1520 树形dp裸题

    1.HDU 1520  Anniversary party 2.总结:第一道树形dp,有点纠结 题意:公司聚会,员工与直接上司不能同时来,求最大权值和 #include<iostream> ...

  4. HDU 1561 树形DP入门

    The more, The Better Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Oth ...

  5. HDU 2196树形DP(2个方向)

    HDU 2196 [题目链接]HDU 2196 [题目类型]树形DP(2个方向) &题意: 题意是求树中每个点到所有叶子节点的距离的最大值是多少. &题解: 2次dfs,先把子树的最大 ...

  6. HDU 1520 树形DP入门

    HDU 1520 [题目链接]HDU 1520 [题目类型]树形DP &题意: 某公司要举办一次晚会,但是为了使得晚会的气氛更加活跃,每个参加晚会的人都不希望在晚会中见到他的直接上司,现在已知 ...

  7. codevs 1380/HDU 1520 树形dp

    1380 没有上司的舞会 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题解 查看运行结果 回到问题 题目描述 Description Ural大学有N个职员 ...

  8. HDU 5834 [树形dp]

    /* 题意:n个点组成的树,点和边都有权值,当第一次访问某个点的时候获得利益为点的权值 每次经过一条边,丢失利益为边的权值.问从第i个点出发,获得的利益最大是多少. 输入: 测试样例组数T n n个数 ...

  9. hdu 4267 树形DP

    思路:先dfs一下,找出1,n间的路径长度和价值,回溯时将该路径长度和价值清零.那么对剩下的图就可以直接树形dp求解了. #include<iostream> #include<al ...

随机推荐

  1. [itint5]单词游戏

    http://www.itint5.com/oj/#36 此题在数据大些,而且全是A的情况下会超时(因为要匹配到很后面才false).通过利用数组本身作为visited标示,而且使用string引用, ...

  2. [topcoder]BadNeighbors

    http://community.topcoder.com/stat?c=problem_statement&pm=2402&rd=5009 动态规划题.对于圈状的题目有了点感觉. 题 ...

  3. SSH 远程连接

    ssh远程连接 准备工作: 1 准备两台linux pc 我们一般用的是VMware虚礼软件 2 这两台linux可以互通 3 linux1 :192.168.2.2 这台为你要连接的服务器 linu ...

  4. Microsoft.Data.ConnectionUI.DataConnectionDialog

    MicrosoftVisualStudio里面的资源之数据库连接配置 这个功能的实现主要是用了Microsoft.Data.ConnectionUI.dll和Microsoft.Data.Connec ...

  5. 判断浏览器类型-----------navigator.userAgent.indexOf()

    <script language="JavaScript"> <!-- function getOs() { var OsObject = "" ...

  6. sed找到重复的行

    sed之仅打印相邻重复的行 cat file  aaa bbb bbb ccc ddd eee eee fff   只显示重复的行: bbb bbb eee eee   sed -n ':a;N;/\ ...

  7. 1067. Disk Tree(字符串)

    1067 破题啊  写完发现理解错题意了 子目录下会有跟之前重名的 把输入的字符串存下来 排下序 然后依次找跟上面有没有重的 #include <iostream> #include< ...

  8. 转: 解决MSYS2下的中文乱码问题

    解决方案 新建/usr/bin/win: 12 #!/bin/bash$@ |iconv -f gbk -t utf-8 新建/etc/profile.d/alias.sh: 12345678 ali ...

  9. 宏FSP_SEG_INODES_PER_PAGE

    #define FSP_SEG_INODES_PER_PAGE(zip_size) \ (((zip_size ? zip_size : UNIV_PAGE_SIZE) \ - FSEG_ARR_OF ...

  10. SDOI2008仪仗队

    这题应该注意到与b2818的不同 一个点能被看见当且仅当它与(1,1)的横纵坐标的距离gcd为1 所以问题转化为x,y<=n-1,求gcd(x,y)=1的方案数 最后要加上2 代码: var i ...