【模版】树的直径
树的直径,即这棵树中距离最远的两个结点的距离。
方法一:用两次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 }
方法二:可以采用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 }

浙公网安备 33010602011771号