AcWing 1073. 树的中心

原题链接

考察:树形dp

1072. 树的最长路径 该题的延伸

思路:

       上题求的是父节点往下的最大值+次大值.这道题求的是点与点的最大距离.这个可以是该点往下的最长距离,也可以是该点往上的最长距离.假设某点为根,往下的最长距离上一题已经求出.往上的最大距离是:到父节点的距离+max(父节点往下的最大距离,父节点往上的最大距离).如果父节点往下的最大距离包括该点,我们要找的就是次最大值,如果不包括,那么就是最大值.

        关于如何求往上的最大距离:我们从根开始往下遍历,对于当前点更新每个子节点的往上距离.

 1 #include <iostream>
 2 #include <cstring>
 3 #include <cstdio>
 4 #include <algorithm>
 5 using namespace std;
 6 const int N = 10010;
 7 struct Road{
 8     int fr,to,ne,w;
 9 }road[N<<1];
10 struct Maxn{
11   int maxs,imax,node,up;  
12 }maxn[N];
13 int h[N],idx,f[N];
14 void add(int a,int b,int c)
15 {
16     road[idx].w = c,road[idx].fr=a,road[idx].to=b,road[idx].ne = h[a],h[a] = idx++;
17 }
18 int dfs(int u,int fa)
19 {
20     int d1 = 0,d2 = 0;
21     for(int i=h[u];i!=-1;i=road[i].ne)
22     {
23         int v = road[i].to;
24         if(v==fa) continue;
25         int d = dfs(v,u)+road[i].w;
26         if(d>=d1) d2 =d1,d1 = d,maxn[u].node = v;
27         else if(d>d2) d2 = d;
28     }
29     maxn[u].maxs = d1,maxn[u].imax = d2;
30     return d1;
31 }
32 int dfs_up(int u,int fa)
33 {
34     for(int i=h[u];i!=-1;i=road[i].ne)
35     {
36         int v = road[i].to;
37         if(v==fa) continue;
38         if(maxn[u].node==v) maxn[v].up = max(maxn[u].imax,maxn[u].up)+road[i].w;
39         else maxn[v].up = max(maxn[u].maxs,maxn[u].up)+road[i].w;
40         dfs_up(v,u);
41     }
42 }
43 int main()
44 {
45     int n,ans = 0x3f3f3f3f;
46     scanf("%d",&n);
47     memset(h,-1,sizeof h);
48     for(int i=1;i<n;i++)
49     {
50         int a,b,c; scanf("%d%d%d",&a,&b,&c);
51         add(a,b,c); add(b,a,c);
52     }
53     dfs(1,-1);
54     dfs_up(1,-1);
55     ans = maxn[1].maxs;
56     for(int i=2;i<=n;i++) ans = min(max(maxn[i].maxs,maxn[i].up),ans);
57     printf("%d\n",ans);
58     return 0;
59 }

 

posted @ 2021-02-15 21:22  acmloser  阅读(84)  评论(0编辑  收藏  举报