樹的直徑 NOIP 2007 樹網的核
阿新 • • 發佈:2018-12-16
題意:求一條直徑上的鏈,要求鏈長,使所有點到這條鏈上的距離中的最大值最小。
首先我們先求出直徑,年輕的時候求直徑也是沒誰了qwq 首先若直徑,我們列舉所有一個在直徑上,一個在直徑外的點對,他們距離的最小值就是答案。 若直徑,我們列舉直徑上的兩點,有定理:對於直徑上任意一個點,到它本身的距離最遠的點一定是直徑的某個端點。所以答案就是 的最小值。
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int INF=999999999;
int e[1000][1000];
int n, s;
int main()
{
cin>>n>>s;
for(int i=1;i<=n;++i)
for(int j=1;j<=n;++j)
{
if(i!=j)
e[i][j]=INF;
else
e[i][j]=0;
}
for(int i=1;i<=n-1;++i)
{
int u,v,d;
scanf("%d%d%d",& u,&v,&d);
e[u][v]=d;
e[v][u]=d;
}
for(int k=1;k<=n;++k)
for(int i=1;i<=n;++i)
for(int j=1;j<=n;++j)
if(e[i][j]>e[i][k]+e[k][j])
e[i][j]=e[i][k]+e[k][j];
int l,r,maxx=0;
for(int i=1;i<=n;++i)
for(int j=1;j<=n;++j)
{
if(e[i][j]!=INF&&e[i][j]>maxx)
{
l=i;
r=j;
maxx=e[i][j];
}
}
int ans=INF;
int maxxx=0;
if(e[l][r]<=s)
{
for(int i=1;i<=n;++i)
if(e[l][i]+e[i][r]==e[l][r])
for(int j=1;j<=n;++j)
if(e[l][j]+e[j][r]!=e[l][r])
ans=min(e[i][j],ans);
cout<<ans;
}
else
{
for(int i=1;i<=n;++i)
if(e[l][i]+e[i][r]==e[l][r])
for(int j=1;j<=n;++j)
if(e[l][j]+e[j][r]==e[l][r])
{
if(e[i][j]>s)
continue;
maxxx=max(min(e[i][l],e[l][j]),min(e[i][r],e[j][r]));
ans=min(ans,maxxx);
}
cout<<ans;
}
return 0;
}