傳送門
描述
給定一棵樹,樹中包含 n 個結點(編號1~n)和 n−1 條無向邊,每條邊都有一個權值。
現在請你找到樹中的一條最長路徑。
換句話說,要找到一條路徑,使得使得路徑兩端的點的距離最遠。
注意:路徑中可以只包含一個點。
輸入格式
第一行包含整數 n。
接下來 n−1 行,每行包含三個整數 ai,bi,ci,表示點 ai 和 bi 之間存在一條權值爲 ci 的邊。
輸出格式
輸出一個整數,表示樹的最長路徑的長度。
數據範圍
1≤n≤10000,
1≤ai,bi≤n,
−105≤ci≤105
輸入樣例:
6
5 1 6
1 4 5
6 3 9
2 6 8
6 1 7
輸出樣例:
22
這道題我們首先考慮建邊的時候建無向邊,然後我們根節點任取一個都行,然後對於每一個節點找到他的子節點分別的最大長度,然後取兩個最
大的,對於每一個節點我們的答案都要進行更新,我們設m1是當前節點子節點的最大值,m2是當前節點的次大值,然後就有
ans=max(ans,m1+m2),這樣就能保證我們找到的答案是最大值,然後返回給上一層的最大值就是m1
注意,m1是返回給上層的最大值,而ans是我們答案的最大值,因爲不一定點多距離就大
#####AC代碼如下:
#include<bits/stdc++.h>
using namespace std;
const int maxn=200010;
int h[maxn],e[maxn],ne[maxn],w[maxn];
int n,m,cnt,ans=0;
bool vis[maxn];
void add(int x,int y,int p) {
w[cnt]=p,e[cnt]=x,ne[cnt]=h[y],h[y]=cnt++;
}
int dfs(int x) {
int res=0,m1=0,m2=0;
vis[x]=true;
for(int i=h[x]; i!=-1; i=ne[i]) {
int y=e[i];
if(!vis[y]) {
int s=dfs(y);
s+=w[i];
if(s>m1)swap(m1,s);
if(s>m2)swap(m2,s);
}
}
ans=max(m1+m2,ans);
return m1;
}
int main() {
cin>>n;
for(int i=0; i<maxn; i++)h[i]=-1;
for(int i=1; i<n; i++) {
int a,b,c;
cin>>a>>b>>c;
add(a,b,c);
add(b,a,c);
}
dfs(1);
cout<<ans<<endl;
return 0;
}