打个手熟
#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;
}