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();
    }
}

时间: 2024-08-02 11:02:00

hdu3622(二分+two-sat)的相关文章

HDU3622(二分+2-SAT)

Bomb Game Time Limit: 10000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 5647    Accepted Submission(s): 2036 Problem Description Robbie is playing an interesting computer game. The game field is an unbounded

hdu3622 2-SAT+二分

http://acm.hdu.edu.cn/showproblem.php?pid=3622 Problem Description Robbie is playing an interesting computer game. The game field is an unbounded 2-dimensional region. There are N rounds in the game. At each round, the computer will give Robbie two p

LA 3211 飞机调度(2—SAT)

https://vjudge.net/problem/UVALive-3211 题意: 有n架飞机需要着陆,每架飞机都可以选择“早着陆”和“晚着陆”两种方式之一,且必须选择一种,第i架飞机的早着陆时间为E,晚着陆时间为L,不得在其他时间着陆.你的任务是为这些飞机安排着陆方式,使得整个着陆计划尽量安全.换句话说,如果把所有飞机的实际着陆时间按照从早到晚的顺序排列,相邻两个着陆时间间隔的最小值. 思路: 二分查找最大值P,每次都用2—SAT判断是否可行. 1 #include<iostream>

hdu-----(1179)Ollivanders: Makers of Fine Wands since 382 BC.(二分匹配)

Ollivanders: Makers of Fine Wands since 382 BC. Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others)Total Submission(s): 935    Accepted Submission(s): 523 Problem Description In Diagon Alley ,there is only one Wand-se

hdu3715 2-sat+二分

Go Deeper 题意:确定一个0/1数组(size:n)使得满足最多的条件数.条件在数组a,b,c给出. 吐槽:哎,一水提,还搞了很久!关键是抽象出题目模型(如上的一句话).以后做二sat:有哪些是点,哪些是条件,分清!,然后注意细节.这次居然因为里面一个小错误: 判断有无解的时候,i与i+1是否在一个SCC中的时候,i居然没有每次+2!而是++!傻X了...囧!还一直以为自己二分写错... #include<iostream> #include<cstdio> #includ

ZOJ 3717 Balloon (二分+2-sat)

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3717 2-sat版题 对半径R进行二分,将二分得到的R用2-sat判,如果2R<dis(i,j),则建边add_and_zero(i,j),然后看是否有解 1 // #pragma comment(linker, "/STACK:102400000,102400000") 2 #include <cstdio> 3 #include <i

2—SAT问题

现有一个由N个布尔值组成的序列A,给出一些限制关系,比如A[x] AND A[y]=0.A[x] OR A[y] OR A[z]=1.A[x] XOR A[y]=0等,要确定A[0..N-1]的值,使得其满足所有限制关系.这个称为SAT问题,特别的,若每种限制关系中最多只对两个元素进行限制,则称为2-SAT问题. 对于x.y有11种关系,将其拆点2x(假),2x+1(真).对于x为假或者y为假这样的条件,我们连两条有向边2x+1->2y.2y+1->2x,注意这里是有向边以及边的起点和终点的关

hdu1179Ollivanders: Makers of Fine Wands since 382 BC. (二分最大匹配)

Problem Description In Diagon Alley ,there is only one Wand-seller,peeling gold letters over the door read Ollivanders: Makers of Fine Wands since 382 BC.A single wand lay on a faded purple cushion in the dusty window. A tinkling bell rang somewhere

UVALive - 3211 (2-SAT + 二分)

layout: post title: 训练指南 UVALive - 3211 (2-SAT + 二分) author: "luowentaoaa" catalog: true mathjax: true tags: - 2-SAT - 图论 - 训练指南 Now or later UVALive - 3211 题意 n架飞机,每架可选择两个着落时间.安排一个着陆时间表,使得着陆间隔的最小值最大 题解 二分查找最大值P,每次都用2-SAT判断是否可行. #include<bits