题解:
求树的直径。
转一篇博客:http://www.cnblogs.com/hanyulcf/archive/2010/10/23/tree_radius.html
树的直径是指树的最长简单路。求法: 两遍BFS :先任选一个起点BFS找到最长路的终点,再从终点进行BFS,则第二次BFS找到的最长路即为树的直径;
原理: 设起点为u,第一次BFS找到的终点v一定是树的直径的一个端点
证明: 1) 如果u 是直径上的点,则v显然是直径的终点(因为如果v不是的话,则必定存在另一个点w使得u到w的距离更长,则于BFS找到了v矛盾)
2) 如果u不是直径上的点,则u到v必然于树的直径相交(反证),那么交点到v 必然就是直径的后半段了
所以v一定是直径的一个端点,所以从v进行BFS得到的一定是直径长度
相关题目有TOJ1056,TOJ3517.
508294 | 609738062@qq.com | 大臣的旅费 | 04-07 20:23 | 1.113KB | C++ | 正确 | 100 | 0ms | 1.238MB | 评测详情 |
代码转自:
http://blog.csdn.net/buctyyzyn/article/details/44886697
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<vector> 6 using namespace std; 7 #define MAXN 10100 8 9 struct Edge{ 10 int v,w; 11 Edge(int vv,int ww):v(vv),w(ww){} 12 }; 13 14 int n; 15 int dist[MAXN],max_len,End; 16 vector<vector<Edge> >G; 17 18 void dfs(int u,int father,int len) 19 { 20 if(len>max_len)max_len=len,End=u; 21 for(int i=0;i<G[u].size();i++){ 22 int v=G[u][i].v,w=G[u][i].w; 23 if(v==father)continue; 24 dist[v]=max(dist[v],len+w); 25 dfs(v,u,len+w); 26 } 27 } 28 29 int main() 30 { 31 int u,v,w; 32 while(~scanf("%d",&n)){ 33 G.clear(); 34 G.resize(n+2); 35 for(int i=1;i<n;i++){ 36 scanf("%d%d%d",&u,&v,&w); 37 G[u].push_back(Edge(v,w)); 38 G[v].push_back(Edge(u,w)); 39 } 40 memset(dist,0,sizeof(dist)); 41 max_len=0; 42 dfs(1,-1,0); 43 memset(dist,0,sizeof(dist)); 44 max_len=0; 45 dfs(End,-1,0); 46 int ans=0; 47 ans=max_len; 48 // for(int i=1;i<=n;i++){ 49 // ans=max(ans,dist[i]); 50 // } 51 int tt=0; 52 for(int i=1;i<=ans;i++) 53 tt+=(10+i); 54 printf("%d ",tt); 55 } 56 return 0; 57 }