ZOJ3717 Balloon(2-SAT)
一个很玄乎的问题,但听到2-SAT之后就豁然开朗了。题目的意思是这样的,给你n个点群,每个点群里面有两个点,你要在每个点群里面选一个点,以这些点做半径为r的圆,然后r会有一个最大值,问的就是怎么选这些点使得r最大。
2-SAT就是对于每个变量有一些制约的关系 a->b 表示选了a就就要选b。然后我们二分这个半径,对于两点间距离<2*r的点(a,b)选了a就不能选b,选了b就不能选a,以此构图。然后跑一次强连通分量。最后判是否有解的时候就是判对于两个属于相同点群的点,它们不能处于同一强连通分量下。写的时候跪的点实在太多了,数组越界呀,强连通写错呀,精度呀,这样的题太坑爹了- -0
#pragma warning(disable:4996)
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<vector>
#define ll long long
#define maxn 220
#define eps 1e-8
using namespace std; struct Point
{
double x, y, z;
Point(double xi, double yi, double zi) :x(xi), y(yi), z(zi){}
Point(){}
}p[maxn * 2]; double dist(Point a, Point b){
return sqrt((a.x - b.x)*(a.x - b.x) + (a.y - b.y)*(a.y - b.y) + (a.z - b.z)*(a.z - b.z));
} double dis[maxn * 2][maxn * 2]; int low[maxn * 2];
int pre[maxn * 2];
int dfs_clock;
int sta[maxn * 2];
int st;
int sccno[maxn * 2];
int n;
vector<int> G[maxn * 2];
int scc_cnt; int dcmp(double x){
return (x > eps) - (x < -eps);
} void dfs(int u){
low[u] = pre[u] = ++dfs_clock;
sta[++st] = u;
for (int i = 0; i < G[u].size(); i++){
int v = G[u][i];
if (!pre[v]){
dfs(v);
low[u] = min(low[u], low[v]);
}
else if (!sccno[v]){
low[u] = min(low[u], pre[v]);
}
}
if (low[u] == pre[u]){
++scc_cnt;
while (1){
int x = sta[st]; st--;
sccno[x] = scc_cnt;
if (x == u) break;
}
}
} bool judge(double x)
{
memset(sccno, 0, sizeof(sccno));
memset(pre, 0, sizeof(pre));
memset(low, 0, sizeof(low));
st = 0; dfs_clock = 0;
scc_cnt = 0;
for (int i = 0; i <= 2 * n; i++) G[i].clear(); for (int i = 0; i < n; i++){
for (int j = i + 1; j < n; j++){
if (dcmp(dis[i][j] - 2 * x) < 0){
G[i].push_back(j + n);
G[j].push_back(i + n);
}
if (dcmp(dis[i][j + n] - 2 * x) < 0){
G[i].push_back(j);
G[j + n].push_back(i + n);
}
if (dcmp(dis[i + n][j] - 2 * x) < 0){
G[i + n].push_back(j + n);
G[j].push_back(i);
}
if (dcmp(dis[i + n][j + n] - 2 * x) < 0){
G[i + n].push_back(j);
G[j + n].push_back(i);
}
}
}
for (int i = 0; i < 2 * n; i++){
if (!pre[i]) dfs(i);
}
for (int i = 0; i < n; i++){
if (sccno[i] == sccno[i + n]) return false;
}
return true;
} int main()
{
while (cin >> n)
{
for (int i = 0; i < n; i++){
scanf("%lf%lf%lf", &p[i].x, &p[i].y, &p[i].z);
scanf("%lf%lf%lf", &p[i + n].x, &p[i + n].y, &p[i + n].z);
}
for (int i = 0; i < 2 * n; i++){
for (int j = i + 1; j < 2 * n; j++){
dis[i][j] = dis[j][i] = dist(p[i], p[j]);
}
}
double l = 0, r = 1e10;
while (dcmp(r - l)>0){
double mid = (l + r) / 2;
if (judge(mid)) l = mid;
else r = mid;
}
int tmp = l * 1000;
double ans = tmp / 1000.0;
printf("%.3lf\n", ans);
}
return 0;
}
ZOJ3717 Balloon(2-SAT)的更多相关文章
- 多边形碰撞 -- SAT方法
检测凸多边形碰撞的一种简单的方法是SAT(Separating Axis Theorem),即分离轴定理. 原理:将多边形投影到一条向量上,看这两个多边形的投影是否重叠.如果不重叠,则认为这两个多边形 ...
- HDOJ 1004 Let the Balloon Rise
Problem Description Contest time again! How excited it is to see balloons floating around. But to te ...
- hdu 1004 Let the Balloon Rise
Let the Balloon Rise Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Oth ...
- 【ZOJ1003】Crashing Balloon(DFS)
Crashing Balloon Time Limit: 2 Seconds Memory Limit: 65536 KB On every June 1st, the Children's ...
- Let the Balloon Rise
Problem Description Contest time again! How excited it is to see balloons floating around. But to te ...
- 杭电1170 Balloon Comes
Problem Description The contest starts now! How excited it is to see balloons floating around. You, ...
- Let the Balloon Rise 分类: HDU 2015-06-19 19:11 7人阅读 评论(0) 收藏
Let the Balloon Rise Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Oth ...
- HDU 1004 Let the Balloon Rise map
Let the Balloon Rise Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Oth ...
- HDU1004 Let the Balloon Rise(map的简单用法)
Let the Balloon Rise Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others ...
随机推荐
- clojure
ide http://updatesite.ccw-ide.org/stable https://cursiveclojure.com/ http://web.clojurerepl.com/ htt ...
- lib和dll的区别,生成(转)
首先介绍下静态库(静态链接库,.lib文件),动态库*(动态链接库,.dll文件)的概念,首先两者都是代码共享的方式. 静态库:在链接步骤中,连接器将从库文件取得所需的代码,复制到生成的可执行文件,这 ...
- C语言如何 实现 下雪效果
题外话 前言 1.本文主要围绕 如何 在 控制台上 下起 一场 只有自己能看见的雪 2.是个简易跨平台的,主要是C语言 3.动画 采用 1s 40帧, 雪花具有 x轴速度和y轴速度 4.比较简单,可 ...
- 关于使用 Connect-Busboy 实现文件上传 优化说明
这篇博文完全上关于上一篇的优化 先看上一篇 node.js 在 Express4.0 框架使用 Connect-Busboy 实现文件上传 因为从上次博客改用 connect-busboy 来上传文件 ...
- 学习XML总结
XML 元素指的是从(且包括)开始标签直到(且包括)结束标签的部分. 元素可包含其他元素.文本或者两者的混合物.元素也可以拥有属性. xml包含如下: 元素 文本 属性 元素 命名: 名称可以含字母. ...
- 浅谈HAL
参考:http://blog.csdn.net/mr_raptor/article/details/8074549 代码实现:http://blog.csdn.net/mr_raptor/articl ...
- Android线程---UI线程和非UI线程之间通信
近期自学到了线程这一块,用了一上午的时间终于搞出来了主.子线程间的相互通信.当主线程sendMessage后,子线程便会调用handleMessage来获取你所发送的Message.我的主线程 ...
- TFS(Taobao File System)安装方法
文章目录: 一.TFS(Taobao File System)安装方法 二.TFS(Taobao File System)配置dataServer.分区.挂载数据盘 三.TFS(Taobao File ...
- 35.在PCB中删除元件
在PCB Editor里面,如果想进行什么操作,首先得点击这个命令,再点击你要操作的区域/元件,最后右键选择"Done",这样你才能完成一个操作.
- homework-01 "最大子数组之和"的解决过程
看到这个题目,我首先想到就是暴力解决 求出所有的子数组的和,取出最大值即可 但其中是可以有优化的 如 子数组[3:6]可以用[3:5]+[6]来计算 即可以将前面的计算结果保留下来,减少后面的重复计算 ...