maximum shortest distance
Problem Description
There are n points in the plane. Your task is to pick k points (k>=2), and make the closest points in these k points as far as possible.
Input
For each case, the first line contains two integers n and k. The following n lines represent n points. Each contains two integers x and y. 2<=n<=50, 2<=k<=n, 0<=x,y<10000.
Output
For each case, output a line contains a real number with precision up to two decimal places.
Sample Input
3 2 0 0 10 0 0 20
Sample Output
22.36
Author
alpc50
Source
题意:
在N个点钟 选出K个点 使得这K个点间的最小距离最大
思路:二分答案+最大团
#include<bits/stdc++.h>
using namespace std;
#define Hash(a,b) (a-1)*n+b
const int maxn=51;
double mp[maxn][maxn];
int num[maxn],k;
int G[maxn][maxn],ret;
bool dfs(int *adj,int tot,int cnt){
if(cnt>=k){
ret=cnt;
return 1;
}
if(tot==0){
if(cnt>ret){
ret=cnt;
return 1;
}
return 0;
}
for(int i=0;i<tot;i++){
if(cnt+tot-i<=ret)
continue;
if(cnt+num[adj[i]]<=ret)
continue;
int t[maxn],k=0;
for(int j=i+1;j<tot;j++){
if(G[adj[i]][adj[j]])
t[k ++] = adj[j];
}
if(dfs(t,k,cnt+1))
return 1;
}
return 0;
}
void Maxclique(int n){
int adj[maxn],tot;
for(int i=n;i>=1;i--){
tot=0;
for(int j=i+1;j<=n;j++)
if(G[i][j]==1)
adj[tot++]=j;
dfs(adj,tot,1);
if(ret>=k)
return ;
num[i]=ret;
}
}
struct Point{
double x,y;
}node[maxn];
double distance(int i,int j){
return sqrt((node[i].y-node[j].y)*(node[i].y-node[j].y)+(node[i].x-node[j].x)*(node[i].x-node[j].x));
}
int main(){
int _;
int n;
while(scanf("%d%d",&n,&k)!=EOF){
memset(G,0,sizeof(G));
ret=0;
for(int i=1;i<=n;i++)
scanf("%lf%lf",&node[i].x,&node[i].y);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
mp[i][j]=distance(i,j);
double low=0,high=20000;
while(high-low>=1e-4){
ret=0;
double mid=(low+high)/2;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++){
if(mp[i][j]>=mid)
G[i][j]=1;
else
G[i][j]=0;
}
Maxclique(n);
if(ret>=k)
low=mid+(1e-4);
else
high=mid-(1e-4);
}
printf("%.2f\n",(high+low)/2);
}
return 0;
}
本文介绍了一个经典的几何问题:从平面上的N个点中选择K个点,使这些点之间的最小距离最大化。通过使用二分查找结合最大团算法的方法来解决此问题,并给出了完整的C++代码实现。
527

被折叠的 条评论
为什么被折叠?



