算法导论 22.2-7 树的直径

 

22.2-7

很显然数的直径就是树的最长简单路。

先进行一次BFS,然后再从BFS的终点再进行一次BFS得到的最长路径就是直径。进行了两次BFS,所以复杂度还O(E+V)

参考自: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得到的一定是直径长度

#include<iostream>  

1. #include<queue>  

2. #define INF 999999  

3. #define M 2002  

4. using namespace std;  

5. int n;  

6. int maxx;  

7. int map[M][M],sum[M];  

8. bool flag[M];  

9. int bfs(int begin){  

10.             queue<int>f;  

11.             int i,m,k,key;  

12.             maxx=0;  

13.             memset(flag,false,sizeof(flag));  

14.             f.push(begin);  

15.             while(!f.empty()){  

16.                         k=f.front();  

17.                          for(i=1;i<=n;i++){  

18.                                  if(map[k][i]!=INF&&!flag[i]){  

19.                                             flag[i]=true;  

20.                                             f.push(i);  

21.                                             sum[i]=sum[k]+map[k][i];  

22.                                              if(sum[i]>maxx) { maxx=sum[i];key=i; }  

23.                                  }  

24.                          }  

25.                          f.pop();  

26.             }  

27.             return key;  

28. }  

29. int main()  

30. {  

31.             int i,j,k,dis,key,cas;  

32.             scanf("%d",&cas);  

33.             while(cas--){  

34.                          scanf("%d",&n);  

35.                          for(i=1;i<n;i++)  

36.                                    for(j=i+1;j<=n;j++)  

37.                                             map[i][j]=map[j][i]=INF;  

38.                          for(i=1;i<n;i++){  

39.                                    scanf("%d%d%d",&j,&k,&dis);  

40.                                    map[j][k]=map[k][j]=dis;  

41.                          }  

42.                          sum[1]=0;  

43.                          key=bfs(1);  

44.                          sum[key]=0;  

45.                          key=bfs(key);  

46.                          printf("%d\n",maxx);  

47.              }  

48.     //system("pause");  

49. }  

你可能感兴趣的:(算法,ini,2010)