Keven现在有一棵树,现在Keven想知道在这颗树上任取两点,他们的距离的最大值是多少,Keven不会做这个题目,于是请教聪明的你,如果你帮助他解决这个问题,他将会让你的排名上升。
树中两点之间的距离定义为连接两点的路径边权之和。并且每条路径经过的次数不能超过1次。
输入格式:
第一行给出一个数字N,表示树的节点个数。(树的节点为1-N)
接下来N-1行,每行给出三个数字U,V,W,表示点U与点V之间有一条权值为W的路径。
(N<200000,W<100000000)
输出格式:
在一行中输出树上任意两点距离的最大值。
输入:
4
1 2 5
1 3 6
1 4 7
输出:
13
样例解释:
- 直接暴搜肯定会T,要剪枝:从根节点开始搜——显然,最大长度会出现在从根节点开始的长度。所以要判断是否只有一条边。
- 用
pair<int,int>
来存点和边,用vector
来存图。 - 每一次从根节点开始暴搜都要初始化v,所以直接把它定义在里面。(定义全局会错)
#include<bits/stdc++.h>
using namespace std;
#define fir(i,a,n) for(int i=a;i<=n;i++)
#define mem(a,x) memset(a,x,sizeof(a));
#define PII pair<int,int>
#define x first
#define y second
#define pb push_back
typedef long long ll;
const int N=2e5+10;
vector<PII>g[N];
int n;
ll ans;
void dfs(int u,int v[],ll sum)//点、标记数组、长度
{
if(v[u]) return;
v[u]=1;
ans=max(ans,sum);
for(auto t:g[u])
{
if(!v[t.x]) dfs(t.x,v,sum+t.y);
}
}
int main()
{
cin>>n;
fir(i,2,n)
{
int a,b,c;scanf("%d%d%d",&a,&b,&c);
g[a].pb({b,c});
g[b].pb({a,c});
}
ans=0;
for(int i=1;i<n;i++)
{
if(g[i].size()==1)//从跟开始找
{
int v[N]={0};//每一次都初始化为0
dfs(i,v,0);
}
}
cout<<ans;
return 0;
}