题意:有n对点,每对点只能选择一个点画圈,要求圈不相交,,问圈的最大半径。。
思路。浮点数计算很花时间,用半径的平方,进行计算。一般的2-sat
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <stack>
using namespace std;
const int INF = 0x3f3f3f3f;
const int N = 209;
struct cvecter{
int x,y;
cvecter(int a,int b){x=a,y=b;}
cvecter(){}
};
int operator*(cvecter &a,cvecter &b){
return a.x*b.x+a.y*b.y;
}
int length(int t){return t<0?-t:t;}
int length(cvecter t){return t*t;}
struct cpoint{
int x,y;
cpoint(int &a,int &b){x=a,y=b;}
cpoint(){}
};
cvecter operator-(cpoint &a,cpoint &b){
return cvecter(a.x-b.x,a.y-b.y);
}
struct cline{
cpoint a,b;
} re[109];
int n;
struct LT{
int to,nex;
}L[N*N];
int F[N],cnt;
void add(int f,int t)
{
L[cnt].nex = F[f];
L[cnt].to = t;
F[f] = cnt++;
}
int dfn[N],low[N],col[N],post[N],color,ind;
stack<int> S;
void tdfs(int k)
{
low[k] = dfn[k] = ++ind;
post[k] = 1;S.push(k);
for(int i=F[k];i;i=L[i].nex)
{
int to = L[i].to;
if(!dfn[to])
{
tdfs(to);
low[k] = min(low[k],low[to]);
}else if(post[to]&&dfn[to]<low[k])
low[k] = dfn[to];
}
if(low[k]==dfn[k])
{
int i;color++;
for(i=S.top(),S.pop();i!=k;i=S.top(),S.pop())
col[i]=color,post[i]=0;
col[k]=color,post[k]=0;
}
}
bool tarjan()
{
memset(dfn,0,sizeof(dfn));
color=0;ind=0;
for(int i=0;i<(n<<1);i++)
if(!dfn[i]) tdfs(i);
for(int i=0;i<n;i++)
if(col[i]==col[i+n]) return false;
return true;
}
void solve()
{
int l=0,r=INF,mid;
int ans;
while(l<=r)
{
mid = (l+r)>>1;
memset(F,0,sizeof(F));cnt=1;
for(int i=0;i<n;i++)
{
for(int j=i+1;j<n;j++)
{
if(length(re[i].a-re[j].a)<mid)
add(i,j+n),add(j,i+n);
if(length(re[i].a-re[j].b)<mid)
add(i,j),add(j+n,i+n);
if(length(re[i].b-re[j].a)<mid)
add(i+n,j+n),add(j,i);
if(length(re[i].b-re[j].b)<mid)
add(i+n,j),add(j+n,i);
}
}
if(tarjan())
ans = mid,l=mid+1;
else r=mid-1;
}
printf("%.2lf\n",sqrt(ans*1.0)/2);
}
int main()
{
freopen("in.txt","r",stdin);
while(~scanf("%d",&n))
{
for(int i=0;i<n;i++)
scanf("%d%d%d%d",&re[i].a.x,&re[i].a.y,&re[i].b.x,&re[i].b.y);
solve();
}
return 0;
}