【模版】树的直径

树的直径,即这棵树中距离最远的两个结点的距离。

 

方法一:用两次bfs,求出1的最远点x,再求x的最远点y,xy即为直径

 1 #include<cstdio>
 2 #define N 10001
 3 #define repu(i,x,y) for(i=x;i<=y;i++)
 4 struct edge{
 5     int v,w;
 6     edge *next;
 7 }e[N],*tp=e,*first[N];
 8 int t,ans;
 9 void add(int u,int v,int w) {
10     *tp=(edge){v,w,first[u]}; first[u]=tp++;
11     *tp=(edge){u,w,first[v]}; first[v]=tp++;
12 }
13 void dfs(int u,int w,int fa) {
14     if (w>ans) ans=w,t=u;
15     for (edge *i=first[u];i;i=i->next) {
16         int v=i->v;
17         if (v!=fa) dfs(v,w+i->w,u);
18     }
19 }
20 int main() {
21     int n,i,x,y,w; scanf("%d",&n);
22     repu(i,1,n-1)
23         scanf("%d%d%d",&x,&y,&w),add(x,y,w);
24     ans=0,dfs(1,0,0);
25     ans=0,dfs(t,0,0);
26     printf("%d\n",ans);
27 }
View Code

 

方法二:可以采用dp做法,基于直径为某个点到其不同子树叶子的最长链+次长链

 1 #include<cstdio>  
 2 #define N 10001  
 3 #define repu(i,x,y) for(i=x;i<=y;i++) 
 4 #define max(a,b) (a>b?a:b) 
 5 struct edge{ 
 6     int v,w;  
 7     edge *next;  
 8 }e[N],*tp=e,*first[N];  
 9 int ans=0; 
10 void add(int u,int v,int w) {  
11     *tp=(edge){v,w,first[u]}; first[u]=tp++;  
12     *tp=(edge){u,w,first[v]}; first[v]=tp++;  
13 }  
14 int dfs(int u,int fa) {  
15     int s1=0,s2=0; 
16     for (edge *i=first[u];i;i=i->next) {  
17         int v=i->v;  
18         if (v!=fa) { 
19             int s=dfs(v,u)+i->w; 
20             if (s>s1) s2=s1,s1=s; 
21             else if (s>s2) s2=s; 
22             ans=max(ans,s1+s2); 
23         } 
24     } 
25     return s1; 
26 }  
27 int main() { 
28     int n,i,x,y,w; scanf("%d",&n);  
29     repu(i,1,n-1)  
30         scanf("%d%d%d",&x,&y,&w),add(x,y,w); 
31     dfs(1,0); 
32     printf("%d\n",ans);  
33 }
View Code

 

posted @ 2017-06-15 13:23  lxtx  阅读(149)  评论(0)    收藏  举报