集训队专题(5.1)1003 maximum shortest distance

来源:互联网 发布:沈阳医疗软件代理 编辑:程序博客网 时间:2024/06/01 09:11

maximum shortest distance

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1386    Accepted Submission(s): 469


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 20 010 00 20
 

Sample Output
22.36
 

Author
alpc50
 

Source
2010 ACM-ICPC Multi-University Training Contest(15)——Host by NUDT
 

此题是一个最大团的变形问题,题目给出k,和n个点,求出n个点之间的距离,让你求出最小的lim,两点距离大于lim算连通,使得最大团的顶点数不小于k。距离方面可以用二分的思想来优化,而最大团直接套小编给出的最大团模板即可。

#include <math.h>#include <cstring>#include <cstdio>#include <algorithm>using namespace std;const int maxn=50+10;int g[maxn][maxn],dp[maxn],stk[maxn][maxn],mx;void dfs(int n, int ns, int dep){    if (ns == 0){        if (dep > mx) mx = dep;        return ;    }    int i,j,k,p,cnt;    for(i=0; i<ns; i++){k = stk[dep][i];cnt = 0;if(dep + n - k <= mx) return ;if(dep + dp[k] <= mx) return ;for(j=i+1; j<ns; j++){p = stk[dep][j];if(g[k][p]) stk[dep+1][cnt++] = p;}dfs(n, cnt, dep+1);}    return ;}int clique(int n){int i,j,ns;for(mx=0, i=n-1; i>=0; i--){for(ns=0, j=i+1; j<n; j++)if(g[i][j]) stk[1][ns++] = j;dfs(n, ns, 1);dp[i] = mx;}return mx;}int x[maxn],y[maxn],n,k;double arc[maxn][maxn],dis[maxn*maxn];bool check(double lim){int i,j;memset(g,0,sizeof(g));for(int i=0; i<n; i++)for(int j=i+1; j<n; j++)if(arc[i][j] >= lim)g[i][j] = g[j][i] = 1;if(clique(n) >= k) return true;else return false;}int main(){int i,j,cnt;while(scanf("%d%d",&n,&k)!=EOF){for(i=0; i<n; i++) scanf("%d%d",&x[i],&y[i]);cnt=0;for(i=0; i<n; i++){arc[i][i] = -1;for(j=i+1; j<n; j++){arc[i][j] = sqrt((double)((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j])));dis[cnt++] = arc[j][i] = arc[i][j];}}sort(dis,dis+cnt);int l=0,r=cnt-1,mid,ans;while(l<=r){mid = (l+r)>>1;if(check(dis[mid])){ans = mid;l = mid+1;}else r = mid-1;}printf("%.2lf\n",dis[ans]);}return 0;}


0 0
原创粉丝点击