acwing 1072. 樹的最長路徑(樹形dp)

傳送門

描述

給定一棵樹,樹中包含 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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章