hdu4607 树直径(两次dfs求向下最远距离及另一方向最远距离相加)

之前有想过树的直径咋求,不过一直没仔细去考虑。

昨天做了hdu2196 今天突然想到如果把max(up[i]+dis1[i])求出来不就是直径maxx嘛==

随后百度了一下看到别人大多数是两次bfs,我从hdu上找了一道题目,果然是可以的。

思想应该是一样的吧,都是求两条最长路。

这题用到最长路还有:

1.k<=maxx+1那么就是k-1

2.k>maxx+1就是(k-maxx-1)*2+maxx+1因为要来回(thinking)

 1 #include<stdio.h>
 2 #include<string.h>
 3 #include<algorithm>
 4 using namespace std;
 5 int next[200005],head[200005],point[200005],value[200005],now;
 6 int dis1[200005],dis2[200005],id[200005],up[200005];
 7 void add(int x,int y,int w)
 8 {
 9   next[++now]=head[x];
10   head[x]=now;
11   point[now]=y;
12   value[now]=w;
13 }
14 void dfs1(int pre,int u)
15 {
16   int i,v,w;
17   dis1[u]=dis2[u]=id[u]=0;
18   for (i=head[u];i;i=next[i])
19   {
20     v=point[i]; w=value[i];
21     if (v==pre) continue;
22     dfs1(u,v);
23     if (dis1[v]+w>dis1[u]){
24       dis1[u]=dis1[v]+w;
25       id[u]=v;
26     }
27   }
28   for (i=head[u];i;i=next[i])
29   {
30     v=point[i]; w=value[i];
31     if (v==pre||v==id[u]) continue;
32     if (dis1[v]+w>dis2[u]) dis2[u]=dis1[v]+w;
33   }
34 }
35 void dfs2(int pre,int u)
36 {
37   int i,v,w;
38   for (i=head[u];i;i=next[i])
39   {
40     v=point[i]; w=value[i];
41     if (v==pre) continue;
42     up[v]=up[u]+w;
43     if (id[u]!=v) up[v]=max(up[v],dis1[u]+w);
44     else up[v]=max(up[v],dis2[u]+w);
45     dfs2(u,v);
46   }
47 }
48 int main()
49 {
50   int n,i,x,y,m,k,maxx,T;
51   scanf("%d",&T);
52   while (T--)
53   {
54     scanf("%d%d",&n,&m);
55     memset(head,0,sizeof(head));
56     now=0;
57     for (i=2;i<=n;i++)
58     {
59       scanf("%d%d",&x,&y);
60       add(x,y,1); add(y,x,1);
61     }
62     memset(dis1,0,sizeof(dis1));
63     memset(dis2,0,sizeof(dis2));
64     memset(id,0,sizeof(id));
65     dfs1(0,1);
66     memset(up,0,sizeof(up));
67     dfs2(0,1);
68     maxx=0;
69     for (i=1;i<=n;i++)
70       maxx=max(maxx,up[i]+dis1[i]);
71     while (m--)
72     {
73       scanf("%d",&k);
74       if (k<=maxx+1) printf("%d\n",k-1);
75       else printf("%d\n",(k-maxx-1)*2+maxx);
76     }
77   }
78   return 0;
79 }
View Code

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4607

转载于:https://www.cnblogs.com/xiao-xin/articles/4234064.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值