센터 트리
트리 주어 각 에지 웨이트를 가지고, 트리에 포함 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;
}