CF266D BerDonalds(图的绝对中心)
https://www.cnblogs.com/suxxsfe/p/15253132.html
图的绝对中心在某节点或边上,使得所有节点到此点的距离最大值最小。
如果绝对中心在点上,那么直接对于每个
考虑在边上的情况,若在边
把这个东西关于
把
实线是
由于斜率一定,可以按照
设
因此若此时有
那么此时
#define N 206
#define M 40006
int n,m;
int val[N];
int dis[N][N],rank[N][N];
int u[M],v[M],w[M];
int main(){
n=read();m=read();
std::memset(dis,0x3f,sizeof dis);
for(reg int i=1;i<=n;i++) dis[i][i]=0;
for(reg int u,v,i=1;i<=m;i++){
u=::u[i]=read();v=::v[i]=read();
dis[u][v]=dis[v][u]=std::min(dis[u][v],w[i]=read());
}
for(reg int k=1;k<=n;k++){
for(reg int i=1;i<=n;i++)for(reg int j=1;j<=n;j++) dis[i][j]=std::min(dis[i][j],dis[i][k]+dis[k][j]);
}
for(reg int i=1;i<=n;i++){
for(reg int j=1;j<=n;j++) val[j]=dis[i][j],rank[i][j]=j;
std::sort(rank[i]+1,rank[i]+1+n,[](const int &a,const int &b){return val[a]<val[b];});
}
int ans=1e9;
for(reg int i=1;i<=n;i++) ans=std::min(ans,dis[i][rank[i][n]]<<1);
for(reg int i=1;i<=m;i++){
int u=::u[i],v=::v[i],w=::w[i];
for(reg int j=n-1,p=n;j;j--)if(dis[v][rank[u][j]]>dis[v][rank[u][p]]){
ans=std::min(ans,dis[u][rank[u][j]]+dis[v][rank[u][p]]+w);
p=j;
}
}
printf("%lf\n",ans/2.0);
return 0;
}