【Luogu P4047】[JSOI2010]部落划分

题目大意:

(n) 个点分组,使得最近的两组最远。

正文:

最近的两组最远 想到二分答案,分组 也可以联想到并查集。用二分答案,很明显二分的是“最近的两组”的距离。而我们可以通过枚举每个点的距离比较当前二分的最近两组距离,如果小于,说明两点皆为同一组内。最后可以通过枚举出的组数比较题目限制的组数调整二分的范围。

代码:

bool check(double x)
{
	for (int i = 1; i <= n; i++) fa[i] = i;
	for (int i = 1; i <= n; i++)
		for (int j = 1; j <= n; j++)
			if((a[i].x - a[j].x - 0.0) * (a[i].x - a[j].x - 0.0) +
				(a[i].y - a[j].y - 0.0) * (a[i].y - a[j].y - 0.0) < x)
					fa[find_(i)] = find_(j);
	int cnt = 0;
	for (int i = 1; i <= n; i++)
		if(fa[i] == i) cnt++;
	if(cnt < k) return 0;
	return 1;
}

int main()
{
	scanf ("%d%d", &n, &k);
	for (int i = 1; i <= n; i++)
		scanf("%d%d", &a[i].x, &a[i].y), 
		maxx = max(a[i].x, maxx), 
		maxy = max(a[i].y, maxy);
	double l = 0.0, r = maxx * maxx + maxy * maxy, mid;
	while(1e-4 < r-l)    //1e-4是精度问题
	{
        mid = (l + r) / 2.0;
        if(check(mid))
            l = mid;
        else
            r = mid;
	}
	printf("%.2lf", sqrt(l));  //最后才取根号是精度问题
	return 0;
}
原文地址:https://www.cnblogs.com/GJY-JURUO/p/13346663.html