树的直径
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 }
以上是关于树的直径的主要内容,如果未能解决你的问题,请参考以下文章
51Nod.1766.树上最远点对(树的直径 RMQ 线段树/ST表)