HDOJ3622-2SAT,二分
来源:互联网 发布:软件企业认定 招标 编辑:程序博客网 时间:2024/04/30 06:30
#include <cstdio>#include <cstring>#include <iostream>#include <cmath>#include <algorithm>#include <vector>using namespace std;const int NN=210; //之前把NN设为了100+导致RE,实在不应该const double eps=0.0001; //精度极小值应设为输出要求精度的%1,WA在这一次struct Edge{ int v,next;}edge[400000];double x[NN],y[NN];double d[NN][NN];int head[NN];int n,ecnt,bcnt,depth,top;int dfn[NN],low[NN],belong[NN],stack[NN];bool instack[NN];void init(){ ecnt=0; for (int i=1; i<=2*n; i++) head[i]=-1; bcnt=0; depth=0; top=0; for (int i=1; i<=n*2; i++) { dfn[i]=0; instack[i]=false; }}void addedge(int u,int v){ edge[ecnt].v=v; edge[ecnt].next=head[u]; head[u]=ecnt++;}double dis(int i,int j){ return sqrt((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]));}void tarjan(int u) //照着模板抄的{ dfn[u]=low[u]=++depth; stack[++top]=u; instack[u]=true; int v; for (int i=head[u]; i!=-1; i=edge[i].next) { v=edge[i].v; if (!dfn[v]) { tarjan(v); low[u]=min(low[u],low[v]); } else if (instack[v]) low[u]=min(low[u],dfn[v]); } if (low[u]==dfn[u]) { bcnt++; do { v=stack[top--]; belong[v]=bcnt; instack[v]=false; }while (v!=u); }}bool two_sat(double r2){ init(); for (int i=1; i<=n; i++) { for (int j=1; j<=n; j++) { if (i==j) continue; //事实是不等式与边的关系还是没理解透,尤其不能理解图的方向性,不过i,j取值均为1~n,这里同时加了同一条边的两个方向这个不难理解 if (d[i][j]-r2<eps) addedge(i,j+n);//addedge(j,i+n); if (d[i][j+n]-r2<eps) addedge(i,j);//addedge(j+n,i+n); if (d[i+n][j]-r2<eps) addedge(i+n,j+n);//addedge(j,i); if (d[i+n][j+n]-r2<eps) addedge(i+n,j);//addedge(j+n,i); } } for (int i=1; i<=2*n; i++) if (!dfn[i]) tarjan(i); for (int i=1; i<=n; i++) { if (belong[i]==belong[i+n]) return false; } return true;}int main(){ while (scanf("%d",&n)!=EOF) { init(); for (int i=1; i<=n; i++) scanf("%lf%lf%lf%lf",&x[i],&y[i],&x[i+n],&y[i+n]); double mm=0; for (int i=1; i<=n*2; i++) for (int j=1; j<=n*2; j++) { d[i][j]=dis(i,j); if (d[i][j]>mm) mm=d[i][j]; } double l=0.0; double r=mm; double mid; while (r-l>eps) //浮点数的二分比整数好写多了 { mid=(l+r)/2; if (two_sat(mid*2)) l=mid; else r=mid; } printf("%.2f\n",mid); } return 0;}