题意:求一条直径上的链,要求链长 < = s <=s <=s,使所有点到这条链上的距离中的最大值最小。
首先我们先求出直径,年轻的时候
n
3
n^3
n3求直径也是没谁了qwq
首先若直径
<
=
s
<=s
<=s,我们枚举所有一个在直径上,一个在直径外的点对,他们距离的最小值就是答案。
若直径
>
s
>s
>s,我们枚举直径上的两点,有定理:对于直径上任意一个点,到它本身的距离最远的点一定是直径的某个端点。所以答案就是
m
a
x
(
m
i
n
(
e
[
i
]
[
l
]
,
e
[
l
]
[
j
]
)
,
m
i
n
(
e
[
i
]
[
r
]
,
e
[
j
]
[
r
]
)
)
;
,
l
,
r
为
直
径
的
两
端
点
,
i
,
j
为
直
径
上
的
点
对
max(min(e[i][l],e[l][j]),min(e[i][r],e[j][r]));,l,r为直径的两端点,i,j为直径上的点对
max(min(e[i][l],e[l][j]),min(e[i][r],e[j][r]));,l,r为直径的两端点,i,j为直径上的点对
的最小值。
#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;
}