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

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 2 0 0 10 0 0 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;
}


你可能感兴趣的:(集训队专题(5.1)1003 maximum shortest distance)