题意:

     给你N组炸弹,每组2个,让你在这N组里面选取N个放置,要求(1)每组只能也必须选取一个(2)炸弹与炸弹之间的半径相等(3)不能相互炸到对方。求最大的可放置半径。

思路:

     二分去枚举半径,然后用2sat去判断是否可行,在2sat里,每组炸弹的两个是正常对,任何两组的任何两个距离小于等于mid那么这两个是矛盾对。这样强连通缩短,然后判断有没有一组是在同一个强连通块里的,没有那么就ok继续更新二分查找答案。

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<stack> #define N_node 200 + 10
#define N_edge 100000 + 100

using namespace
std; typedef struct
{
int
to ,next;
}
STAR; typedef struct
{
double
x1 ,x2 ,y1 ,y2;
}
NODE; STAR E1[N_edge] ,E2[N_edge];
NODE node[111];
int
list1[N_node] ,list2[N_node] ,tot;
int
Belong[N_node] ,cnt;
int
mark[N_node];
stack<int>st; void add(int a , int b)
{

E1[++tot].to = b;
E1[tot].next = list1[a];
list1[a] = tot; E2[tot].to = a;
E2[tot].next = list2[b];
list2[b] = tot;
} void
DFS1(int s)
{

mark[s] = 1;
for(int
k = list1[s] ;k ;k = E1[k].next)
{
int
xin = E1[k].to;
if(!
mark[xin]) DFS1(xin);
}

st.push(s);
} void
DFS2(int s)
{

mark[s] = 1;
Belong[s] = cnt;
for(int
k = list2[s] ;k ;k = E2[k].next)
{
int
xin = E2[k].to;
if(!
mark[xin]) DFS2(xin);
}
} double
diss(double x1 ,double y1 ,double x2 ,double y2)
{
double
tmp = (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2);
return
sqrt(tmp);
} bool
ok(double mid ,int n)
{

memset(list1 ,0 ,sizeof(list1));
memset(list2 ,0 ,sizeof(list2));
tot = 1;
for(int
i = 0 ;i < n ;i ++)
for(int
j = i + 1 ;j < n ;j ++)
{
int
a ,b;
double
dis = diss(node[i].x1 ,node[i].y1 ,node[j].x1 ,node[j].y1);
if(
dis <= mid)
{

a = i * 2 ,b = j * 2;
add(a ,b^1) ,add(b ,a^1);
}

dis = diss(node[i].x1 ,node[i].y1 ,node[j].x2 ,node[j].y2);
if(
dis <= mid)
{

a = i * 2 ,b = j * 2 + 1;
add(a ,b^1) ,add(b ,a^1);
}

dis = diss(node[i].x2 ,node[i].y2 ,node[j].x1 ,node[j].y1);
if(
dis <= mid)
{

a = i * 2 + 1,b = j * 2;
add(a ,b^1) ,add(b ,a^1);
}

dis = diss(node[i].x2 ,node[i].y2 ,node[j].x2 ,node[j].y2);
if(
dis <= mid)
{

a = i * 2 + 1,b = j * 2 + 1;
add(a ,b^1) ,add(b ,a^1);
}
}

memset(mark ,0 ,sizeof(mark));
while(!
st.empty())st.pop();
for(int
i = 0 ;i < n * 2 ;i ++)
if(!
mark[i]) DFS1(i);
memset(mark ,0 ,sizeof(mark));
cnt = 0;
while(!
st.empty())
{
int
xin = st.top();
st.pop();
if(
mark[xin]) continue;
++
cnt;
DFS2(xin);
}
int
mk = 0;
for(int
i = 0 ;i < n * 2 ;i += 2)
{
if(
Belong[i] == Belong[i^1])
mk = 1;
}
return !
mk;
} int main ()
{
int
n ,i;
while(~
scanf("%d" ,&n))
{
for(
i = 0 ;i < n ;i ++)
scanf("%lf %lf %lf %lf" ,&node[i].x1 ,&node[i].y1 ,&node[i].x2 ,&node[i].y2);
double
low ,mid ,up ,ans = 0;
low = 0 ,up = 2000000000;
for(
i = 1 ;i <= 100 ;i ++)
{

mid = (low + up) / 2;
if(
ok(mid ,n))
ans = low = mid;
else
up = mid;
}

printf("%.2lf\n" ,ans/2);
}
return
0;
}

hdu3622 二分+2sat的更多相关文章

  1. HDU3622(二分+2-SAT)

    Bomb Game Time Limit: 10000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  2. HDU 3622 Bomb Game(二分+2SAT)

    题意:有一个游戏,有n个回合,每回合可以在指定的2个区域之一放炸弹,炸弹范围是一个圈,要求每回合的炸弹范围没有重合.得分是炸弹半径最小的值.求可以得到的最大分数. 思路:二分+2SAT. 二分炸弹范围 ...

  3. hdu 3622 二分+2-sat

    /* 二分+2-sat 题意:在一个二维平面上给你n个炸弹,和2*n个位置,每一行的两个位置只能有一个放炸弹 现在炸弹爆炸有一个半径,当炸弹爆炸时两个炸弹的半径化成的圆不能相交,求最大半径 二分半径, ...

  4. hdu1816 + POJ 2723开锁(二分+2sat)

    题意:      有m层门,我们在最外层,我们要一层一层的进,每一层上有两把锁,我们只要开启其中的一把们就会开,我们有n组钥匙,每组两把,我们只能用其中的一把,用完后第二把瞬间就会消失,问你最多能开到 ...

  5. HDU3622 Bomb Game(二分+2-SAT)

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

  6. 二分+2-sat——hdu3062

    hdu3622升级版 注意要保留两位小数 /* 给定n对圆心(x,y),要求从每对里找到一个点画圆,不可相交 使得最小半径最大 二分答案,设最小半径为r 然后两两配对一次进行判断,在2-sat上连边即 ...

  7. hdu 3622 Bomb Game(二分+2-SAT)

    Bomb Game Time Limit: 10000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total ...

  8. POJ 2296 二分+2-sat

    题目大意: 给定n个点,给每个点都安排一个相同的正方形,使这个点落在正方形的下底边的中间或者上底边的中间,并让这n个正方形不出现相互覆盖,可以共享同一条边,求 这个正方形最大的边长 这里明显看出n个点 ...

  9. 【UVALive - 3211】Now or later (二分+2-SAT)

    题意: 有n架飞机需要着陆.每架飞机有两种选择,早着陆或者晚着陆,二选其一.现在为了保证飞机的着陆安全,要求两架着陆的飞机的时间间隔的最小值达到最大. 分析: 最小值最大问题我们想到二分答案.对于猜测 ...

随机推荐

  1. LeetCode-重建二叉树(前序遍历+中序遍历)

    重建二叉树 LeetCode-105 首次需要知道前序遍历和中序遍历的性质. 解题思路如下:首先使用前序比遍历找到根节点,然后使用中序遍历找到左右子树的范围,再分别对左右子树实施递归重建. 本题的难点 ...

  2. 1.1 Python3基础-前言

    >>返回主目录 Python 交互式代码 Python 脚本式代码 第一段Python代码: print('Hello World!') >>返回主目录

  3. Azure AD, Endpoint Manger(Intune), SharePoint access token 的获取

    本章全是干货,干货,干货,重要的事情说三遍. 最近在研究Azure, Cloud相关的东西,项目中用的是Graph API(这个在下一章会相信介绍),可能是Graph API推出的时间比较晚,部分AP ...

  4. vue项目安装sass步骤等遇到的问题

    1.安装sass依赖包 npm install --save-dev sass-loader 注释(可能会出现问题:sass-loader版本过高导致,可以将其package.json中的版本改为7. ...

  5. NET 5.0 Swagger API 自动生成MarkDown文档

    目录 1.SwaggerDoc引用 主要接口 接口实现 2.Startup配置 注册SwaggerDoc服务 注册Swagger服务 引用Swagger中间件 3.生成MarkDown 4.生成示例 ...

  6. 递归函数初步理解---python实现(汉诺塔问题)

    递归常被用来描述以自相似的方法重复事物的过程,在程序中指的是在函数定义中使用函数自身的方法. 递归是一个树结构,分为递推和回归的过程,当递推到达底部时,就会开始回归. 问题描述:A比B大两岁,B比C大 ...

  7. ch1_6_6求解门禁系统问题

    import java.util.HashMap; import java.util.Scanner; public class ch1_6_6求解门禁系统问题 { public static voi ...

  8. 【linux】驱动-7-平台设备驱动

    目录 前言 7. 平台设备驱动 7.1 平台总线 7.1.1 平台总线注册和匹配方式 7.1.2 源码分析 7.2 平台设备 7.2.1 platform_device 7.2.2 设备信息 7.2. ...

  9. 数据表设计之主键自增、UUID或联合主键

    最近在做数据库设计的时候(以MySQL为主),遇到不少困惑,因为之前做数据库表设计,基本上主键都是使用自增的形式,最近因为这种做法,被领导指出存在一些不足,于是我想搞明白哪里不足. 一.MySQL为什 ...

  10. docker部署kafka集群

    利用docker可以很方便的在一台机子上搭建kafka集群并进行测试.为了简化配置流程,采用docker-compose进行进行搭建. kafka搭建过程如下: 编写docker-compose.ym ...