一个很玄乎的问题,但听到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)的更多相关文章

  1. 多边形碰撞 -- SAT方法

    检测凸多边形碰撞的一种简单的方法是SAT(Separating Axis Theorem),即分离轴定理. 原理:将多边形投影到一条向量上,看这两个多边形的投影是否重叠.如果不重叠,则认为这两个多边形 ...

  2. HDOJ 1004 Let the Balloon Rise

    Problem Description Contest time again! How excited it is to see balloons floating around. But to te ...

  3. hdu 1004 Let the Balloon Rise

    Let the Balloon Rise Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Oth ...

  4. 【ZOJ1003】Crashing Balloon(DFS)

    Crashing Balloon Time Limit: 2 Seconds      Memory Limit: 65536 KB On every June 1st, the Children's ...

  5. Let the Balloon Rise

    Problem Description Contest time again! How excited it is to see balloons floating around. But to te ...

  6. 杭电1170 Balloon Comes

    Problem Description The contest starts now! How excited it is to see balloons floating around. You, ...

  7. 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 ...

  8. 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 ...

  9. HDU1004 Let the Balloon Rise(map的简单用法)

    Let the Balloon Rise Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others ...

随机推荐

  1. 刀哥多线程全局队列gcd-09-global_queue

    全局队列 是系统为了方便程序员开发提供的,其工作表现与并发队列一致 全局队列 & 并发队列的区别 全局队列 没有名称 无论 MRC & ARC 都不需要考虑释放 日常开发中,建议使用& ...

  2. C# ArrayList的用法总结

    C# ArrayList的用法总结 System.Collections.ArrayList类是一个特殊的数组.通过添加和删除元素,就可以动态改变数组的长度. 一.优点 1. 支持自动改变大小的功能 ...

  3. c语言的结构体字节数统计

    struct结构体的字节数 等于 结构体中最大类型的字节数的倍数. 如: typedef struct Student{    short id; //2个字节    char name[15]; / ...

  4. Some Tips About VS2015

    Xaml edit bug about vs2013+ sometimes, vs will say some class not found in the namespace. but, we co ...

  5. ultraedit高亮显示设置

    ultraedit高亮显示设置 | 浏览:2333 | 更新:2014-02-20 23:05 1 2 3 4 5 6 7 分步阅读 百度经验:jingyan.baidu.com 写代码的人对ultr ...

  6. homework-03 扑街。。

    1.思路 我的思路是利用进程间通信间来实现题目要求. 第一次打开的程序与第二次打开的程序并不是同一个进程,故需要进程间通信来是传递信息. windows下进程间通信的方式有很多,如文件映射.共享内存. ...

  7. cameralink---格式 概要清晰理解

    DS90CR288 和DS90CR286共同组成LVDS收发对, LVDS: 4对数据+1对时钟 TTL: 时钟线1:clk 并行总线共27根: 同步线2:一根场同步,一根行同步 空闲: 1 数据线2 ...

  8. 三,samba

    转载:http://www.cnblogs.com/phinecos/archive/2009/06/06/1497717.html 一. samba的安装: sudo apt-get insall  ...

  9. curl库 c语言的curl 编程

    c语言的curl 编程 [Linux@centos-64-min exercise]# gcc -Wall -o curltest curltest.c /tmp/ccosVANi.o: In fun ...

  10. 【工作总结】LLDB调试技巧 - 篇一

    备忘命令 : 命令“l”可以查看程序当前运行的位置 (lldb) l } - (void)rightBarButtonAction { 命令“bt”也能查看程序运行的调用栈 (lldb) bt * t ...