HDU 3622 2-SAT+二分

来源:互联网 发布:php图书管理系统实例 编辑:程序博客网 时间:2024/05/17 06:37

猪头说:

很多题目要求 最大的XX 或者最小的XX 就用二分来做
具体的判定用2-sat来实现
基本都是这样的

 

这题就是二分枚举半径,用2-SAT来判定是否可行,求可能的最大的半径

 

#include<stdio.h>#include<stdlib.h>#include<math.h>#include<iostream>#include<string.h>#include<algorithm>#include<queue>#include<vector>#include<map>#include<string>#define ll __int64typedef long long LL;#define INF 0x7fffffffffffffff#define inf 0x7fffffff#define eps 1e-10#define pi acos(-1.0)#define FRE freopen("in.txt","r",stdin)#define E exp(1.0)#define log2(x) log((x))/log(2.0)#define maxn 210#define maxe 50010using namespace std;struct point{    int x,y;}p[maxn];struct node{    int v,next;}edge[maxe];int n;int size,head[maxn];int dfn[maxn],low[maxn],scc[maxn],sstack[maxn],instack[maxn];int idex,top,cnt;void init(){    memset(head,-1,sizeof(head));    memset(dfn,-1,sizeof(dfn));    memset(instack,0,sizeof(instack));    idex=cnt=size=0;top=-1;}void addedge(int u,int v){    edge[size].v=v;    edge[size].next=head[u];    head[u]=size++;}void tarjan(int u){    sstack[++top]=u;    instack[u]=1;    dfn[u]=low[u]=idex++;    for(int i=head[u];i!=-1;i=edge[i].next)    {        int v=edge[i].v;        if(dfn[v]==-1)        {            tarjan(v);;            low[u]=min(low[u],low[v]);        }        else if(instack[v])        {            low[u]=min(low[u],dfn[v]);        }    }    if(dfn[u]==low[u])    {        for(int v=-1;v!=u;top--)        {            v=sstack[top];            instack[v]=0;            scc[v]=cnt;        }        cnt++;    }}void work(){    for(int i=1;i<=2*n;i++)    {        if(dfn[i]==-1)        tarjan(i);    }}bool check(){    for(int i=1;i<=n;i++)    {        if(scc[i]==scc[i+n])        return false;    }    return true;}double dist(point p1,point p2){    return sqrt(1.0*(p1.x-p2.x)*(p1.x-p2.x)+1.0*(p1.y-p2.y)*(p1.y-p2.y));}void build(double mid){    int i,j;    for(i=1;i<=n;i++)    {        for(j=i+1;j<=n;j++)        {            if(dist(p[i],p[j])<2*mid)            {               addedge(i,j+n);               addedge(j,i+n);            }            if(dist(p[i],p[j+n])<2*mid)            {                addedge(i,j);                addedge(j+n,i+n);            }            if(dist(p[i+n],p[j])<2*mid)            {                addedge(i+n,j+n);                addedge(j,i);            }            if(dist(p[i+n],p[j+n])<2*mid)            {                addedge(i+n,j);                addedge(j+n,i);            }        }    }}void binsearch(){    double l=0.0,r=20000;    while(r-l>eps)    {        double mid=(l+r)/2.0;        init();        build(mid);        work();        if(check())        l=mid;        else        r=mid;    }    printf("%.2lf\n",l);}int main() {   FRE;   while(scanf("%d",&n)==1)   {       int i,j;       for(i=1;i<=n;i++)       {           scanf("%d%d%d%d",&p[i].x,&p[i].y,&p[i+n].x,&p[i+n].y);       }       binsearch();   }   return 0;}


 

 

 

原创粉丝点击