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 }