Computer(树的直径做法)
重要性质:树上任意点能到的最远点,一定是树的直径的某个端点。
解题思路:根据上述性质,先求出树的直径,然后从直径的两个端点u和v分别DFS整棵树,对于每个结点得到两个距离d[i].u和d[i].v, 二者的最大值即是i点能到的最远点的距离
AC_Code:
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <cstring> 5 #include <string> 6 using namespace std; 7 typedef long long ll; 8 const int maxn = 1e4+10; 9 const int inf = 0x3f3f3f3f; 10 const int mod = 998244353; 11 #define rep(i,first,second) for(int i=first;i<=second;i++) 12 #define dep(i,first,second) for(int i=first;i>=second;i--) 13 14 struct edge{ int to,nxt,val;}e[maxn<<1]; 15 int head[maxn<<1],maxdis,maxv,tot; 16 int vis[maxn],d1[maxn],d2[maxn]; 17 int n; 18 19 void add(int u,int v,int w){ 20 e[tot].to = v; 21 e[tot].nxt = head[u]; 22 e[tot].val = w; 23 head[u] = tot++; 24 } 25 26 void dfs(int u,int f,int dis,int d[]){ 27 d[u]=dis; 28 if( d[maxv]<d[u] ) maxv = u; 29 for(int i=head[u];~i;i=e[i].nxt){ 30 int v=e[i].to,w=e[i].val; 31 if( v==f ) continue; 32 dfs(v,u,dis+w,d); 33 } 34 } 35 36 int main() 37 { 38 while( ~scanf("%d",&n) ){ 39 memset(head,-1,sizeof(head)); 40 tot=0; 41 42 rep(i,2,n){ 43 int u,v,w; 44 scanf("%d%d",&v,&w); 45 u=i; 46 add(u,v,w); 47 add(v,u,w); 48 } 49 50 int s; 51 s=1; maxv=0; d1[maxv]=0; 52 dfs(s,-1,0,d1); 53 54 s=maxv; d1[maxv]=0; 55 dfs(s,-1,0,d1); 56 57 s=maxv; d2[maxv]=0; 58 dfs(s,-1,0,d2); 59 60 rep(i,1,n){ 61 printf("%d\n",max(d1[i],d2[i])); 62 } 63 } 64 return 0; 65 }