您的位置:首页 > 其它

树的直径

2016-05-29 16:59 218 查看
自己写挫了...借鉴的别人的代码...

题目链接: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的距离,其中的最大值即为树的直径

代码:

#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <vector>
#include <iostream>
using namespace std;
#define for0(i, n) for(int i=0; i<(n); ++i)
#define for1(i,a,n) for(int i=(a);i<=(n);++i)
#define for2(i,a,n) for(int i=(a);i<(n);++i)
#define for3(i,a,n) for(int i=(a);i>=(n);--i)
#define for4(i,a,n) for(int i=(a);i>(n);--i)
#define CC(i,a) memset(i,a,sizeof(i))
#define LL long long
#define MOD 1000000007
#define INF 0x3f3f3f3f
#define PI 3.1415926
#define N 10010

struct Edge
{
Edge(){}
Edge(int to,int cost,int next):to(to),cost(cost),next(next){}
int to;
int cost;
int next;
}edge[N*N];  //所有边
int cnt;       //边总数
int head
;//头结点
int dis
;
//添加两条有向边
void AddEdge(int u,int v,int cost)
{
edge[cnt]=Edge(v,cost,head[u]);
head[u]=cnt++;
edge[cnt]=Edge(u,cost,head[v]);
head[v]=cnt++;
}

//BFS返回从s结点能走到的最远的点的编号
int bfs(int s)
{
int max_dis=0;//记录最远距离
int id=s;      //记录最远点
queue<int> Q;
memset(dis,-1,sizeof(dis));
dis[s]=0;
Q.push(s);
while(!Q.empty())
{
int u=Q.front(); Q.pop();
if(dis[u]>max_dis)
{
max_dis=dis[u];
id=u;
}
for(int i=head[u];i!=-1;i=edge[i].next)
{
Edge e=edge[i];
if(dis[e.to]==-1)//未访问过e.to点
{
dis[e.to]=dis[u]+e.cost;
Q.push(e.to);
}
}
}
return id;
}

int main()
{
int u,v,cost;
memset(head,-1,sizeof(head));
cnt=0;
while(scanf("%d%d%d",&u,&v,&cost)==3)
AddEdge(u,v,cost);
printf("%d\n",dis[bfs(bfs(u))]);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: