二分檢索。注意這裏有個陷阱,存在多個共存的區域。
/*******************************************************************************
# Author : Neo Fung
# Email : [email protected]
# Last modified: 2012-06-19 21:51
# Filename: ZOJ3370 Radio Waves.cpp
# Description :
******************************************************************************/
#ifdef _MSC_VER
#define DEBUG
#define _CRT_SECURE_NO_DEPRECATE
#endif
#include <fstream>
#include <stdio.h>
#include <iostream>
#include <string.h>
#include <string>
#include <limits.h>
#include <algorithm>
#include <math.h>
#include <numeric>
#include <functional>
#include <ctype.h>
#include <queue>
using namespace std;
const int kMAX=1210;
const double kEPS=1E-9;
double map[kMAX][kMAX];
int ans[kMAX];
// 點的定義
struct POINT{
double x,y;
}point[kMAX];
// 計算兩點的距離
double inline Distance(const POINT &lhs,const POINT &rhs)
{
return sqrt((lhs.x-rhs.x)*(lhs.x-rhs.x)+(lhs.y-rhs.y)*(lhs.y-rhs.y));
}
int n;
int used[kMAX];
bool Check(const double &x)
{
memset(used,-1,sizeof(used));
for(int i=0;i<n;++i)
{
if(used[i]>-1)
continue;
queue<int> q;
q.push(i);
used[i]=0;
while(!q.empty())
{
int now=q.front();
q.pop();
for(int j=0;j<n;++j)
{
if(j==now || map[now][j]>x)
continue;
if(used[j]==used[now])
return false;
if(used[j]==-1)
{
used[j]=1-used[now];
q.push(j);
}
}
}
}
for(int i=0;i<n;++i)
ans[i]=used[i]+1;
return true;
}
// 二分檢索,l是左起點座標,r是右起點座標(包含r)
// Check 爲判定函數,根據需要改變
double BinSearch(double l, double r)
{
while(l+kEPS<r){
double mid=(l+r)/2;
if (Check(mid))
l=mid;
else
r=mid;
}
return l;
}
int main(void)
{
#ifdef DEBUG
freopen("../stdin.txt","r",stdin);
freopen("../stdout.txt","w",stdout);
#endif
while(~scanf("%d",&n) && n)
{
for(int i=0;i<n;++i)
{
scanf("%lf%lf",&point[i].x,&point[i].y);
for(int j=0;j<i;++j)
map[i][j]=map[j][i]=Distance(point[i],point[j]);
}
double tmp=BinSearch(0.0,40000.0);
printf("%.17lf\n",tmp*0.5);
for(int i=0;i<n;++i)
printf("%d%c",ans[i],i==(n-1)?'\n':' ');
}
return 0;
}