센터 트리 트리 DP-

센터 트리

트리 주어 각 에지 웨이트를 가지고, 트리에 포함 N 노드들 (1 ~ N 번째) 및 n-1 방향성 에지.

그래서 가장 멀리 떨어져있는 다른 노드 트리 점 요즘 트리의 지점을 찾아주세요.

입력 포맷은
첫 번째 행은 정수 n을 포함한다.

포인트 A1 및 바이 사이 다음에, N-1 로우는 3의 정수를 포함하는 각각의 행은 AI, BI는 CI는 CI는 에지의 존재의 중량을 나타낸다.

출력 형식
트리를 나타내는 정수 출력은 다른 노드의 가장 먼 지점을 찾을 수 있습니다.

데이터 범위
1≤n≤10000,
1≤ai, bi≤n,
-105≤ci≤105
입력 샘플 :
. 5
2 1 1
. 3 1 2
. 4. 3. 1
. 1. 제 1
출력 샘플을 :
2

해결 방법 :

이 질문은 우리가 최소 거리를 보장 할 수있을 때 중앙에 원형으로 우리의 첫 번째 트리의 중심에서 가장 큰 최소 요구 트리뿐만 아니라 수 있도록해야합니다. 그래서 우리 나무의 중심은 같은 이유입니다. 우리는 루트 상단과 가장 긴 거리가 가장 긴 거리의 바닥에서 지점을 찾은 다음 두 가지의 작은 값을 먹고 싶어. 그래서 우리는 두 번 트리 DP가 필요합니다. 최대 일단 아래로 한 번. 를 들어 우리는 리프 노드 위쪽으로 할 수 있습니다. 무슨 일이 이전 질문에 다소 유사하며 장소는 무엇입니까? 에서 처리하는 우리가 가장 큰 아래로 같은 거리에서 루트 노드의 동일한 수준에서 우리에게이 노드 아래있을 때. 우리가 (최대 최소를 보장하기로) 또 다른 두 번째 큰 거리를 선택할 수 있도록 우리가이 노드가 아닌 경우, 그러나, 우리는 (최대 보장하기로) 최대 거리를 포함하는 노드로 이동할 수 있습니다.

#include<bits/stdc++.h>
using namespace std;
const int N=2e4+7,inf=0x3f3f3f3f;
int ne[N],h[N],w[N],e[N],cnt,d1[N],d2[N],r1[N],r2[N],up[N];
bool lef[N];
void add(int a,int b,int c)
{
	e[cnt]=b,w[cnt]=c,ne[cnt]=h[a],h[a]=cnt++;
}
int dfs_d(int u,int f)
{
	d1[u]=d2[u]=-inf;
	for(int i=h[u];i!=-1;i=ne[i]){
		int j=e[i];
		if(j==f) continue;
		int d=dfs_d(j,u)+w[i];
		if(d>=d1[u]){
			d2[u]=d1[u]; d1[u]=d;
			r2[u]=r1[u]; r1[u]=j;
		}else if(d>=d2[u]) d2[u]=d,r2[u]=j;
	}
	if(d1[u]==-inf){
		d1[u]=d2[u]=0;
		lef[u]=1;
	}
	return d1[u];
}
int dfs_u(int u,int f)
{
	for(int i=h[u];i!=-1;i=ne[i]){
		int j=e[i];
		if(j==f) continue;
		if(r1[u]==j) up[j]=max(up[u],d2[u])+w[i];
		else up[j]=max(up[u],d1[u])+w[i];
		dfs_u(j,u);
	}
}
int main()
{
	int n; cin>>n;
	memset(h,-1,sizeof h);
	for(int i=1;i<n;i++){
		int a,b,c; cin>>a>>b>>c;
		add(a,b,c),add(b,a,c);
	}
	dfs_d(1,-1);
	dfs_u(1,-1);
	int res=d1[1];
	for(int i=2;i<=n;i++){
		if(lef[i]) res=min(res,up[i]);
		else res=min(res,max(d1[i],up[i]));
	} 
	cout<<res<<endl;
}
发布了76 篇原创文章 · 获赞 4 · 访问量 681

추천

출처blog.csdn.net/weixin_42979819/article/details/103944969