资源限制
时间限制:100ms 内存限制:8.0MB
问题描述
树的直径
输入格式
输入的第一行包含一个整数n,表示树中的点数。接下来n-1行,每行3个正整数,表示连同的两点及边的权值。
输出格式
输出1行,包含一个整数,表示树的直径。
样例输入
7
1 2 1
1 3 1
2 4 1
3 5 1
4 7 1
4 6 1
样例输出
5
数据规模和约定
n<10^5
思路:
树的直径:找相距最远两点之间的距离,即为树的直径。
从任一点出发,找到距离该点最远的点 p1, p1 必定为直径的一个端点。 (跑一遍dfs)
从p1出发,找到距离p1最远的点p2,p2必定为直径的另一个端点,所以p1,p2两点连线是相距最远的两点,即为树的直径。 (再跑一遍dfs)
代码:
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
const int maxn=1e5+10;
struct node{
int v,w;
node(int a,int b){v=a;w=b;}
};
int n,a,b,c,p1,maxlen=0;
vector<node> g[maxn]; //图
bool vis[maxn]={false}; //是否走过
void dfs(int u,int dis)
{
if(dis>maxlen) //更新最远距离和最远点
{
maxlen=dis;
p1=u;
}
for(int i=0;i<g[u].size();i++)
{
int v=g[u][i].v;
int w=g[u][i].w;
if(!vis[v]) //没访问过
{
vis[v]=1;
dfs(v,dis+w);
vis[v]=0; //回溯
}
}
}
int main()
{
cin>>n;
for(int i=0;i<n-1;i++)
{
cin>>a>>b>>c;
g[a].push_back(node(b,c));
g[b].push_back(node(a,c));
}
vis[1]=1;
dfs(1,0); //从任一点出发,这里从1出发
vis[1]=0;
maxlen=0; // 最远距离
vis[p1]=1;
dfs(p1,0); //从p1出发,能最远距离就是树的直径
vis[p1]=0;
cout<<maxlen;
return 0;
}