hdu 3622 二分+2-SAT判定

思路:如题

#include<iostream>

#include<algorithm>

#include<cstring>

#include<cstdio>

#include<cmath>

#define Maxm 100010

#define eps 1e-4

using namespace std;

int vi[220],head[220],e,n,m,id[220],lab,num,dfn[220],low[220],Stack[220],top;

double Max;

struct Point{

    double x,y;

}p[210];

struct Edge{

    int u,v,next;

}edge[Maxm];

void init()

{

    memset(vi,0,sizeof(vi));

    memset(head,-1,sizeof(head));

    memset(dfn,0,sizeof(dfn));

    memset(low,0,sizeof(low));

    lab=num=top=0;

    e=0;

}

void add(int u,int v)

{

    edge[e].u=u,edge[e].v=v,edge[e].next=head[u],head[u]=e++;

}

double Dis(Point a,Point b)

{

    return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));

}

void Tarjan(int u)

{

    int i,j,v;

    dfn[u]=low[u]=++lab;

    Stack[top++]=u;

    vi[u]=1;

    for(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]);

        }

        if(vi[v])

            low[u]=min(low[u],dfn[v]);

    }

    if(low[u]==dfn[u])

    {

        ++num;

        do{

            i=Stack[--top];

            vi[i]=0;

            id[i]=num;

        }while(i!=u);

    }

}

int solve()

{

    int i,j;

    for(i=1;i<=2*n;i++)

        if(!dfn[i])

        Tarjan(i);

    for(i=1;i<=n;i++)

        if(id[i]==id[i+n])

        return 0;

    return 1;

}

void buildGraphic(double mid)

{

    init();

    int i,j;

    for(i=1;i<=n;i++)

    {

        for(j=i+1;j<=n;j++)

        {

            if(Dis(p[i],p[j])<mid)

                add(i,j+n),add(j,i+n);

            if(Dis(p[i+n],p[j+n])<mid)

                add(i+n,j),add(j+n,i);

        }

        for(j=1+n;j<=2*n;j++)

        {

            if(j==i+n) continue;

            if(Dis(p[i],p[j])<mid)

                add(i,j-n),add(j,i+n);

        }

    }

}

int main()

{

    int i,j;

    while(scanf("%d",&n)!=EOF)

    {

        init();

        for(i=1;i<=n;i++)

            scanf("%lf%lf%lf%lf",&p[i].x,&p[i].y,&p[i+n].x,&p[i+n].y);

        double l,r,mid;

        l=0,r=40000;

        while(l+eps<r)

        {

            mid=(l+r)/2;

            buildGraphic(mid*2);

            if(solve())

                l=mid;

            else

                r=mid;

        }

        printf("%.2lf\n",l);

    }

    return 0;

}

 

你可能感兴趣的:(HDU)