打个手熟

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<math.h>

#define N 105*2
#define M 40000+5
#define ll double
#define eps 1e-5

using namespace std;

inline ll Max(ll a,ll b){return a>b?a:b;}
inline ll Min(ll a,ll b){return a<b?a:b;}

struct Point{
	double x,y;
}p[N];
inline double dist(Point a,Point b){return sqrt((double)((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)));}

struct Edge{
	int to, nex;
}edge1[M],edge2[M];

int head1[N],head2[N], edgenum1, edgenum2;
void addedge(int u, int v){
	edge1[edgenum1]. to = v;
	edge1[edgenum1]. nex = head1[u];
	head1[u] = edgenum1 ++;
	edge2[edgenum2]. to = u;
	edge2[edgenum2]. nex = head2[v];
	head2[v] = edgenum2 ++;
}

bool vis1[N], vis2[N];
int belong[N], T[N];
int Bcnt, Tcnt;

void dfs1(int x){
	vis1[x] = true;
	for(int i = head1[x]; i!=-1; i = edge1[i].nex)
		if(!vis1[edge1[i].to])
			dfs1(edge1[i].to);
	T[Tcnt++] = x;
}
void dfs2(int x){
	vis2[x] = true;
	belong[x] = Bcnt;
	for(int i = head2[x]; i!=-1; i = edge2[i].nex)
		if(!vis2[edge2[i].to])
			dfs2(edge2[i].to);
}



void init(){
	memset(head1, -1, sizeof(head1));
	memset(head2, -1, sizeof(head2));
	memset(vis1, 0, sizeof(vis1));
	memset(vis2, 0, sizeof(vis2));
	edgenum1 = edgenum2 = 0;
	Bcnt = Tcnt = 0;
}

bool ok(int n){
	for(int i = 0; i < n; i++)
		if(!vis1[i])dfs1(i);
	
	for(int i = Tcnt -1; i>=0; i--)
	{
		if(!vis2[T[i]])
		{
			dfs2(T[i]);
			Bcnt++;
		}
	}

	for(int i = 0; i<n; i+=2)
		if(belong[i] == belong[i+1])
			return false;
	return true;
}

int main(){
	int n, i, j;
	while(~scanf("%d",&n)){
		n <<= 1;
		for(i = 0;i < n; i++)scanf("%lf %lf",&p[i].x,&p[i].y);

		double left = 0, right = 40000;
		while(right - left >= eps)
		{
			double mid = (left + right) / 2;
			init();
			for(i = 0;i < n; i++)
			{
				for(j = i+1+!(i&1); j < n; j++)
				if(dist(p[i],p[j])<2*mid)
				{
					addedge(i, j^1);
					addedge(j, i^1);
				}
			}
			if(ok(n))left = mid;
			else right = mid;
		}
		printf("%.2lf\n",right);
	}
return 0;
}


 再来一发白书板子

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<math.h>

#define ll double
#define eps 1e-5

using namespace std;

inline ll Max(ll a,ll b){return a>b?a:b;}
inline ll Min(ll a,ll b){return a<b?a:b;}


#define N 105*2
#define M 40000+5

struct Edge{
	int to, nex;
}edge[M];

int head[N], edgenum;
void addedge(int u, int v){
	Edge E = {v, head[u]};
	edge[edgenum] = E;
	head[u] = edgenum ++;
}

bool mark[N];
int Stack[N], top;
void init(){
	memset(head, -1, sizeof(head)); edgenum = 0;
	memset(mark, 0, sizeof(mark));
}

bool dfs(int x){
	if(mark[x^1])return false;//一定是拆点的点先判断
	if(mark[x])return true;

	mark[x] = true;
	Stack[top++] = x;

	for(int i = head[x]; i != -1; i = edge[i].nex)
		if(!dfs(edge[i].to)) return false;

	return true;
}

bool solve(int n){
	for(int i = 0; i < n; i+=2)
		if(!mark[i] && !mark[i^1])
		{
			top = 0;
			if(!dfs(i))
			{
				while( top ) mark[ Stack[--top] ] = false;
				if(!dfs(i^1)) return false;
			}
		}
	return true;
}

struct Point{
	double x,y;
}p[N<<1];
inline double dist(Point a,Point b){return sqrt((double)((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)));}

int main(){
	int n, i, j;
	while(~scanf("%d",&n)){
		n <<= 1;
		for(i = 0;i < n; i++)scanf("%lf %lf",&p[i].x,&p[i].y);

		double left = 0, right = 40000;
		while(right - left >= eps)
		{
			double mid = (left + right) / 2;
			init();
			for(i = 0;i < n; i++)
			{
				for(j = i+1+!(i&1); j < n; j++)
					if(dist(p[i],p[j])<2*mid)//冲突了
					{
						addedge(i, j^1);
						addedge(j, i^1);
					}
			}
			if(solve(n))left = mid;
			else right = mid;
		}
		printf("%.2lf\n",right);
	}
	return 0;
}