ZOJ 3717 二分+2-sat判定
The weather is wonderful today. Gao takes a walk in the garden with his girlfriend. His girlfriend likes balloons so much, so that she wants to fly some balloons (not kites!) in the garden.
We can regard the garden as a three-dimensional space, and its coordinate starts from (0,0,0) to (10000,10000,10000). There are N groups of balloons, each of groups has a red balloon and a blue balloon. We can regard each balloon as a sphere, all the radius of spheres are R. The center of each sphere will be given in the input.
For some reasons, she wants to choose one balloon (red one or blue one) from each group, so that she can put exactly N balloons in the garden. It's obvious that there is no overlap for any two balloons in the N balloons which she selected. The largest R will make Gao's girlfriend happiest. Can you help Gao to calculate the largest R?
Input
There are multiple cases. For each case, The first line contains an integer N (2 ≤ N ≤ 200), meaning there are N groups of balloons. In the next N lines, each line contains six integers, indicating the coordinates of two balloons.
NOTICE: The garden only limits the center of the balloon.
Output
For each test case, it contains one real number indicating the largest R. The results should be rounded to three decimal places. You should promise that there is still no overlap for any two balloons after rounded.
Sample Input
2 1 1 1 5 5 5 1 1 1 5 5 5
Sample Output
3.464
题意,解题思路:题意和hdu 3622一样,做法也一模一样,一个2D,一个3D,貌似此题卡精度,wa好多次,特殊处理才过。
代码:
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<map>
#include<string>
#include<vector>
#include<stack>
#include<math.h>
#include<iomanip>
using namespace std;
const double eps=1e-8;
const int maxn=500;
const int maxm=1000000;
struct point
{
double x,y,z;
}p[maxn];
double dis(point a,point b)
{
double ss=a.x-b.x;
double tt=a.y-b.y;
double pp=a.z-b.z;
return sqrt(ss*ss+tt*tt+pp*pp);
}
int head[maxn],tol,low[maxn],dfn[maxn],Stack[maxn],instack[maxn],belong[maxn],scc,top,indexx,n;
struct node
{
int next,to;
}edge[maxm];
void add(int u,int v)
{
edge[tol].next=head[u];
edge[tol].to=v;
head[u]=tol++;
}
void tarjin(int u)
{
low[u]=dfn[u]=++indexx;
Stack[top++]=u;instack[u]=1;
int i,v;
for(i=head[u];i!=-1;i=edge[i].next)
{
v=edge[i].to;
if(!dfn[v])
{
tarjin(v);
if(low[u]>low[v])low[u]=low[v];
}
else if(instack[v]&&low[u]>dfn[v])low[u]=dfn[v];
}
if(low[u]==dfn[u])
{
scc++;
do
{
v=Stack[--top];
instack[v]=0;
belong[v]=scc;
}while(u!=v);
}
}
int solve(double r)
{
memset(head,-1,sizeof(head));tol=0;
int i,j,u,v;
for(i=0;i<2*n;i++)
{
int pp;
if(i%2==0)pp=i+2;
else pp=i+1;
for(j=pp;j<2*n;j++)
if(dis(p[i],p[j])+eps<2*r)
{
add(i,j^1);
add(j,i^1);
}
}
memset(dfn,0,sizeof(dfn));
memset(instack,0,sizeof(instack));
memset(belong,0,sizeof(belong));
scc=top=indexx=0;
for(i=0;i<2*n;i++)if(!dfn[i])tarjin(i);
for(i=0;i<n;i++)
if(belong[2*i]==belong[2*i+1])return 0;
return 1;
}
int main()
{
int i,j,k,m;
while(~scanf("%d",&n))
{
for(i=0;i<n;i++)
{
scanf("%lf%lf%lf",&p[2*i].x,&p[2*i].y,&p[2*i].z);
scanf("%lf%lf%lf",&p[2*i+1].x,&p[2*i+1].y,&p[2*i+1].z);
}
double left=0.0,right=10000.0,mid;
while(right-left>eps)
{
mid=(left+right)/2.0;
i=solve(mid);
if(i==0)right=mid;
else left=mid;
}
char str[222] ;
sprintf(str,"%.3f",left) ;
sscanf(str,"%lf",&left) ;
if(!solve(left))left-=0.001;
printf("%.3f\n",left);
}
return 0;
}

浙公网安备 33010602011771号