【2012百度之星/初赛下】B:网页聚类

描述:有N(N2+ (y_j-y_i)2 + (z_j-z_i)2。请求出最大的t,使得N个网页可以聚成K类,其中每个类至少包含一个网页,且任意两个位于不同类中网页的相似度都至少为t。

输入

第一行包含两个整数N和K,后面N行每行三列,分别为x、y、z。

输出

最大的t的值,使用四舍五入在小数点后保留六位小数。

样例输入

5 3

0.1 0.2 0.4

0.2 0.8 0.7

0.3 0.4 0.5

0.0 0.5 0.0

0.3 0.3 0.2

样例输出

0.170000

#include<iostream>
#include<cstdio>
#include<queue>
#include<vector>
using namespace std; 

const int MAXN = 2010;
const double EPS = 1e-8;

double x[MAXN], y[MAXN], z[MAXN], d[MAXN][MAXN];
bool vis[MAXN];
int n, k, cnt, belong[MAXN];
queue <int> q;
vector <int> e[MAXN];
vector <int> :: iterator iter; 

double dist(int i, int j)
{
	return (x[i] - x[j]) * (x[i] - x[j]) + (y[i] - y[j]) * (y[i] - y[j]) + (z[i] - z[j]) * (z[i] - z[j]);
}
void bfs(int p)
{
	memset(vis , 0 , sizeof(vis));
	q.push(p);
	while (!q.empty())
	{
		int u = q.front();
		q.pop();
		belong[u] = cnt, vis[u] = true;
		for(iter = e[u].begin(); iter != e[u].end(); ++iter)
		{
			if (!vis[*iter])
				q.push(*iter);
		}
	}
}
bool check(double t)
{
	int i, j;
	for (i = 0; i < n; ++i)
	{
		e[i].clear();
		for (j = 0; j < n; ++j)
		{
			if (d[i][j] < t && i != j)
			{
				e[i].push_back(j);
			}
		}
	}
	cnt = 0;
	for (i = 0; i < n; ++i)
	{
		if (!belong[i])
		{
			cnt++;
			bfs(i);
		}
	}
	return cnt >= k;
}
int main(void)
{
	int i, j;
	scanf("%d %d", &n, &k);
	for (i = 0; i < n; ++i)
	{
		scanf("%lf %lf %lf", &x[i], &y[i], &z[i]);
	}
	for (i = 0; i < n; ++i)
	{
		for (j = 0; j < n; ++j)
		{
			d[i][j] = dist(i, j);
		}
	}
	double l = 0, r = 3;
	while (r - l > EPS)
	{
		memset(belong , 0 , sizeof(belong));
		double mid = (l + r) / 2;
		if( check(mid) )
			l = mid;
		else
			r = mid;
	}
	printf("%.6lf\n", l);
	return 0;
}


你可能感兴趣的:(vector,百度,iterator,n2,2010)