hdu3622(二分+two-sat)

 

传送门:Bomb Game

题意:给n对炸弹可以放置的位置(每个位置为一个二维平面上的点),每次放置炸弹是时只能选择这一对中的其中一个点,每个炸弹爆炸的范围半径都一样,控制爆炸的半径使得所有的爆炸范围都不相交(可以相切),求解这个最大半径.

分析:二分距离,由two-sat判可行性,建图时对于每两个炸弹的两个位置,互相判断一下是否冲突,冲突就建边。

#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <queue>
#include <cstdlib>
#include <stack>
#include <vector>
#include <set>
#include <map>
#define LL long long
#define mod 100000000
#define inf 0x3f3f3f3f
#define eps 1e-6
#define N 210
#define FILL(a,b) (memset(a,b,sizeof(a)))
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define PII pair<int,int>
using namespace std;
struct edge
{
    int v,next;
    edge() {}
    edge(int v,int next):v(v),next(next) {}
} e[N*N];
int n,m,scc,step,top,tot;
int head[N],dfn[N],low[N],belong[N],Stack[N];
bool instack[N];
void init()
{
    tot=0;step=0;
    scc=0;top=0;
    FILL(head,-1);
    FILL(dfn,0);
    FILL(low,0);
    FILL(instack,false);
}
void addedge(int u,int v)
{
    e[tot]=edge(v,head[u]);
    head[u]=tot++;
}
void tarjan(int u)
{
    int v;
    dfn[u]=low[u]=++step;
    Stack[top++]=u;
    instack[u]=true;
    for(int i=head[u]; ~i; i=e[i].next)
    {
        v=e[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(dfn[u]==low[u])
    {
        scc++;
        do
        {
            v=Stack[--top];
            instack[v]=false;
            belong[v]=scc;
        }
        while(v!=u);
    }
}
int judge()
{
    for(int i=0; i<2*n; i++)
        if(!dfn[i])tarjan(i);
    for(int i=0; i<n; i++)
    {
        if(belong[i<<1]==belong[i<<1^1])
        {
            return 0;
        }
    }
    return 1;
}

int lx[105],ly[105],rx[105],ry[105];
double dist(int a,int b,int x,int y)
{
    return sqrt((double)(a-x)*(a-x)+(double)(b-y)*(b-y));
}
void build(double m)
{
    for(int i=0;i<n;i++)
        for(int j=i+1;j<n;j++)
        {
            if(dist(lx[i],ly[i],lx[j],ly[j])+eps<2*m)addedge(i<<1,j<<1|1),addedge(j<<1,i<<1|1);
            if(dist(lx[i],ly[i],rx[j],ry[j])+eps<2*m)addedge(i<<1,j<<1),addedge(j<<1|1,i<<1|1);
            if(dist(rx[i],ry[i],lx[j],ly[j])+eps<2*m)addedge(i<<1|1,j<<1|1),addedge(j<<1,i<<1);
            if(dist(rx[i],ry[i],rx[j],ry[j])+eps<2*m)addedge(i<<1|1,j<<1),addedge(j<<1|1,i<<1);
        }
}
void solve()
{
    double l=0,r=40000,ans=0;
    while(r-l>eps)
    {
        double m=(l+r)/2;
        init();
        build(m);
        if(judge())
        {
            ans=m;l=m;
        }
        else r=m;
    }
    printf("%.2f\n",ans);
}
int main()
{
    int a,b,c,u,v;
    char op[10];
    while(scanf("%d",&n)>0)
    {
        for(int i=0;i<n;i++)
        {
            scanf("%d%d%d%d",&lx[i],&ly[i],&rx[i],&ry[i]);
        }
        solve();
    }
}
View Code

 

posted on 2015-02-10 17:54  lienus  阅读(115)  评论(0编辑  收藏  举报

导航