树的直径(最长路)

树间距离最长的两点所形成的路径叫做树的最长路

设这条路为s->t.

很容易想到的方法是以每个点为起点当做s,然后dfs求t。  时间复杂度是O(V*(V+E))

但有更简单的方法是,以任意点u进行dfs找到最远点,这个最远点为s或t,然后以这个最远点进行dfs,即可找到最长路

那么如何证明以任意点u进行dfs找到最远点,这个最远点为s或t呢??

为了写证明更简洁,我们设这点最远点为t

证明如下:

(1)点u为最长路s->t上的点,那么以u为起点搜到的最远点肯定为s或t,如果不是,那么很显然,s->t不是最长路

(2)点u不是最长路上的点,那么又分为两种情况

  a:以点u搜到的最远点形成的路径与s->t有交点x,那么这条路的形成分为两个步骤,从u走到x,再从x搜最远点(又回到了第一种情况),

  b:以点u搜到的最远点为T的路径与s->t没有交点,又因为图是联通的,那么可以从u走出一条路,该路与s->t有交点k。那么如图

  树的直径(最长路)

那么 dist(u,T) > dist(u,k) + dist(k,t)

-->dist(u,T) > dist(k,t)

-->dist(u,T) + dist(s,k)+dist(u,k) > dist(k,t) + dist(s,k) = dist(s,t)

那么最长路就变成了dist(u,T) + dist(s,k)+dist(u,k)。与假设矛盾

 

所以又上面的证明可知,

以任意点u进行dfs找到最远点,这个最远点为s或t(以任意点出发的最长路与树的最长路一定有交点)

 http://lx.lanqiao.org/problem.page?gpid=T32

 1 #include <stdio.h>

 2 #include <string.h>

 3 #include <vector>

 4 using namespace std;

 5 const int N = 10000 + 10;

 6 struct node

 7 {

 8     int v,next,cost;

 9 }g[N*2];

10 int e,head[N];

11 bool vis[N];

12 void addEdge(int u, int v, int cost)

13 {

14     g[e].v = v;

15     g[e].cost = cost;

16     g[e].next = head[u];

17     head[u] = e++;

18 }

19 int maxDist,index;

20 void dfs(int u, int dist)

21 {

22     if(dist > maxDist)

23     {

24         maxDist = dist;

25         index = u;

26     }    

27     for(int i=head[u]; i!=-1; i=g[i].next)

28     {

29         int v = g[i].v;

30         if(!vis[v])

31         {

32             vis[v] = true;

33             dfs(v,dist+g[i].cost);

34             vis[v] = false;

35         }

36 

37     }

38 }

39 int main()

40 {

41     int n,u,v,c,i;

42     scanf("%d",&n);

43     memset(head,-1,sizeof(head));

44     for(i=1; i<n; ++i)

45     {

46         scanf("%d%d%d",&u,&v,&c);

47         addEdge(u,v,c);

48         addEdge(v,u,c);

49     }

50     memset(vis,0,sizeof(vis));

51     vis[i] = true;

52     dfs(i,0);

53     memset(vis,0,sizeof(vis));

54     vis[index] = true;

55     dfs(index,0);

56     printf("%d\n",maxDist*10 + (1+maxDist)*maxDist/2);

57     return 0;

58 }
View Code

 

你可能感兴趣的:(树)