树的直径

Posted C-DmLy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了树的直径相关的知识,希望对你有一定的参考价值。

自己写挫了...借鉴的别人的代码...

 

题目链接:http://poj.org/problem?id=2631

题解链接:http://blog.csdn.net/v5zsq/article/details/50654640

 

Description 
给出一棵无向树,求树的直径,即树上两点之间的最长距离 
Input 
每行三个整数a,b,c表示树上a点与b点之间有权值为c的一条边,以文件尾结束输入 
Output 
输出树的直径 
Sample Input 
5 1 6 
1 4 5 
6 3 9 
2 6 8 
6 1 7 
Sample Output 
22 
Solution 
先给出一个结论: 
从任一点s出发,距此点距离最远的点为直径的一个端点a,那么距a最远的点b即为直径的另一个端点,a与b之间的距离即为直径长度 
此题为求树的直径裸题,分两部分,首先从任一点出发开始dfs,不妨从1开始,用树形dp求出任一点距1点的距离,找到距其最远点s,然后以s为起点再dfs一遍,求出所有点距s的距离,其中的最大值即为树的直径 

 

 

代码:

 1 #include <cstdio>
 2 #include <cmath>
 3 #include <cstring>
 4 #include <string>
 5 #include <algorithm>
 6 #include <queue>
 7 #include <stack>
 8 #include <map>
 9 #include <set>
10 #include <vector>
11 #include <iostream>
12 using namespace std;
13 #define for0(i, n) for(int i=0; i<(n); ++i)
14 #define for1(i,a,n) for(int i=(a);i<=(n);++i)
15 #define for2(i,a,n) for(int i=(a);i<(n);++i)
16 #define for3(i,a,n) for(int i=(a);i>=(n);--i)
17 #define for4(i,a,n) for(int i=(a);i>(n);--i)
18 #define CC(i,a) memset(i,a,sizeof(i))
19 #define LL long long
20 #define MOD 1000000007
21 #define INF 0x3f3f3f3f
22 #define PI 3.1415926
23 #define N 10010
24 
25 struct Edge  
26 {  
27     Edge(){}  
28     Edge(int to,int cost,int next):to(to),cost(cost),next(next){}  
29     int to;  
30     int cost;  
31     int next;  
32 }edge[N*N];  //所有边  
33 int cnt;       //边总数  
34 int head[N];//头结点  
35 int dis[N];
36 //添加两条有向边  
37 void AddEdge(int u,int v,int cost)  
38 {  
39     edge[cnt]=Edge(v,cost,head[u]);  
40     head[u]=cnt++;  
41     edge[cnt]=Edge(u,cost,head[v]);  
42     head[v]=cnt++;  
43 }
44   
45 //BFS返回从s结点能走到的最远的点的编号  
46 int bfs(int s)  
47 {  
48     int max_dis=0;//记录最远距离  
49     int id=s;      //记录最远点  
50     queue<int> Q;  
51     memset(dis,-1,sizeof(dis));  
52     dis[s]=0;  
53     Q.push(s);  
54     while(!Q.empty())  
55     {  
56         int u=Q.front(); Q.pop();  
57         if(dis[u]>max_dis)  
58         {  
59             max_dis=dis[u];  
60             id=u;  
61         }  
62         for(int i=head[u];i!=-1;i=edge[i].next)  
63         {  
64             Edge e=edge[i];  
65             if(dis[e.to]==-1)//未访问过e.to点  
66             {  
67                 dis[e.to]=dis[u]+e.cost;  
68                 Q.push(e.to);  
69             }  
70         }  
71     }  
72     return id;  
73 }  
74   
75 int main()  
76 {  
77     int u,v,cost;  
78     memset(head,-1,sizeof(head));  
79     cnt=0;  
80     while(scanf("%d%d%d",&u,&v,&cost)==3)  
81         AddEdge(u,v,cost);  
82     printf("%d\n",dis[bfs(bfs(u))]);  
83     return 0;  
84 }  

 

以上是关于树的直径的主要内容,如果未能解决你的问题,请参考以下文章

jzoj3555树的直径

[dfs][树的直径] Jzoj P1737 删边

[SDOI2011]消防(单调队列,树的直径,双指针)

51Nod.1766.树上最远点对(树的直径 RMQ 线段树/ST表)

树的直径 bzoj3363[Usaco2004 Feb]Cow Marathon 奶牛马拉松

BZOJ3124 直径