题目描述
A公司想在N个城市中选择M个来开维修店,而购买了A公司产品的人如果要维修,可以送到最近的维修店。A公司想知道,选择哪些城市开维修店可以使得离维修店最远的那个城市离维修店的距离尽量小。给出N个城市的坐标(城市的坐标是唯一的),你能帮A公司求出这个最小的距离吗?
输入
repair.in的第一行包含两个整数,分别是城市数N以及维修店数M。
接下来的N行各包含两个数,分别是每个城市的X坐标和Y坐标。
输出
repair.out只有一行,包含一个小数,为所求的最小距离,保留2位有效数字。
思路
这道题先预处理任意2个城市之间的距离,然后做全排列,每做出一个全排列就计算距离求最小
code:
#pragma once
#pragma GCC diagnostic error "-std=c++11"
#pragma GCC target("avx")
#pragma GCC optimize(2)
#pragma GCC optimize(3,"Ofast","inline")
#pragma GCC optimize("Ofast")
#pragma GCC optimize("inline")
#pragma GCC optimize("-fgcse")
#pragma GCC optimize("-fgcse-lm")
#pragma GCC optimize("-fipa-sra")
#pragma GCC optimize("-ftree-pre")
#pragma GCC optimize("-ftree-vrp")
#pragma GCC optimize("-fpeephole2")
#pragma GCC optimize("-ffast-math")
#pragma GCC optimize("-fsched-spec")
#pragma GCC optimize("unroll-loops")
#pragma GCC optimize("-falign-jumps")
#pragma GCC optimize("-falign-loops")
#pragma GCC optimize("-falign-labels")
#pragma GCC optimize("-fdevirtualize")
#pragma GCC optimize("-fcaller-saves")
#pragma GCC optimize("-fcrossjumping")
#pragma GCC optimize("-fthread-jumps")
#pragma GCC optimize("-funroll-loops")
#pragma GCC optimize("-fwhole-program")
#pragma GCC optimize("-freorder-blocks")
#pragma GCC optimize("-fschedule-insns")
#pragma GCC optimize("inline-functions")
#pragma GCC optimize("-ftree-tail-merge")
#pragma GCC optimize("-fschedule-insns2")
#pragma GCC optimize("-fstrict-aliasing")
#pragma GCC optimize("-fstrict-overflow")
#pragma GCC optimize("-falign-functions")
#pragma GCC optimize("-fcse-skip-blocks")
#pragma GCC optimize("-fcse-follow-jumps")
#pragma GCC optimize("-fsched-interblock")
#pragma GCC optimize("-fpartial-inlining")
#pragma GCC optimize("no-stack-protector")
#pragma GCC optimize("-freorder-functions")
#pragma GCC optimize("-findirect-inlining")
#pragma GCC optimize("-fhoist-adjacent-loads")
#pragma GCC optimize("-frerun-cse-after-loop")
#pragma GCC optimize("inline-small-functions")
#pragma GCC optimize("-finline-small-functions")
#pragma GCC optimize("-ftree-switch-conversion")
#pragma GCC optimize("-foptimize-sibling-calls")
#pragma GCC optimize("-fexpensive-optimizations")
#pragma GCC optimize("-funsafe-loop-optimizations")
#pragma GCC optimize("inline-functions-called-once")
#pragma GCC optimize("-fdelete-null-pointer-checks")//八聚氧——打开你所有的运算速度开关
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<map>
#include<string>
#include<cmath>
using namespace std;
int n,m;
double b[22][22];
struct f{
int x,y;
} a[22];
int o[22];
bool o2[22];
double mx=9999999;
double f(int p)
{
double mxn=0;
for (int j=1;j<=n;j++)
{
double mn=9999999;
for (int i=0;i<p;i++)
{
mn=min(mn,b[j][o[i]]);
}
mxn=max(mn,mxn);
}
return mxn;
}//计算距离
void dfs(int x)
{
if (x>=m)
{
mx=min(mx,f(m));
return;
}
for (int i=o[x-1]+1;i<=n;i++)
{
if (o2[i]) continue;
o[x]=i;
o2[i]=1;
dfs(x+1);
o2[i]=0;
}
return;
}//枚举全排列
int main()
{
cin>>n>>m;
if (m==n)
{
cout<<"0.00";
return 0;
}
for (int i=1;i<=n;i++)
{
scanf("%d%d",&a[i].x,&a[i].y);
}
for (int i=1;i<=n;i++)
{
for (int j=1;j<=n;j++)
{
b[i][j]=sqrt((a[j].x-a[i].x)*(a[j].x-a[i].x)+(a[j].y-a[i].y)*(a[j].y-a[i].y));
}
}//b[i][j]为从i到j的距离,预处理
dfs(0);
printf("%.2f",mx);//2位小数
return 0;
}