Computer(树的直径做法)

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 }

 

posted @ 2020-04-06 20:15  swsyya  阅读(221)  评论(0编辑  收藏  举报

回到顶部