题意:
在一个三维空间中..可以放气球..每次给两个气球..必须并且仅可放一个气球..现在要求所放气球都没有冲突..请求出最长的半径是多少..
题解:
一看就是2-sat+二分了..和HDU 3622一回事...WA了好多发..原因是输出的精度..吐..
Program:
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<set>
#include <stack>
#include<queue>
#include<algorithm>
#include<cmath>
#define eps 1e-4
#define oo 1000000007
#define MAXN 505
#define ll long long
#define pi acos(-1.0)
using namespace std;
struct NODE
{
int x,y,z;
}P[MAXN];
struct node
{
int v,next;
}edge[MAXN*MAXN];
int Ne,_next[MAXN],dfn[MAXN],low[MAXN],DfsIndex,tp[MAXN],tpnum;
bool inS[MAXN];
stack<int> S;
double dis[MAXN][MAXN];
void addedge(int u,int v)
{
edge[++Ne].next=_next[u],_next[u]=Ne,edge[Ne].v=v;
}
void tarjan(int u)
{
int k,v;
dfn[u]=low[u]=++DfsIndex;
inS[u]=true,S.push(u);
for (k=_next[u];k;k=edge[k].next)
{
v=edge[k].v;
if (!dfn[v])
{
tarjan(v);
low[u]=min(low[u],low[v]);
}else
if (inS[v])
low[u]=min(low[u],dfn[v]);
}
if (dfn[u]==low[u])
{
tpnum++;
do
{
u=S.top(),S.pop();
inS[u]=false;
tp[u]=tpnum;
}while (dfn[u]!=low[u]);
}
}
bool ok(int n,double d)
{
int i,j;
Ne=0,memset(_next,0,sizeof(_next));
for (i=0;i<n<<1;i++)
for (j=i+1;j<n<<1;j++)
if (dis[i][j]<d) addedge(i,j^1),addedge(j,i^1);
memset(dfn,0,sizeof(dfn));
memset(inS,false,sizeof(inS));
while (!S.empty()) S.pop();
DfsIndex=tpnum=0;
for (i=0;i<n<<1;i++)
if (!dfn[i]) tarjan(i);
for (i=0;i<n;i++)
if (tp[i<<1]==tp[i<<1|1]) return false;
return true;
}
int main()
{
int n,i,j;
double l,r,mid;
while (~scanf("%d",&n))
{
for (i=0;i<n;i++)
scanf("%d%d%d",&P[i<<1].x,&P[i<<1].y,&P[i<<1].z),
scanf("%d%d%d",&P[i<<1|1].x,&P[i<<1|1].y,&P[i<<1|1].z);
for (i=0;i<n<<1;i++)
for (j=0;j<n<<1;j++)
dis[i][j]=sqrt((P[i].x-P[j].x)*(P[i].x-P[j].x)
+(P[i].y-P[j].y)*(P[i].y-P[j].y)
+(P[i].z-P[j].z)*(P[i].z-P[j].z));
l=0,r=oo;
while (r-l>eps)
{
mid=(r+l)/2;
if (ok(n,mid*2)) l=mid;
else r=mid;
}
printf("%.3lf\n",l-0.0005);
}
return 0;
}