/*2-sat问题初破!题意:每一对炸弹只能选一个(明显2-sat),每个炸弹半径自定,爆炸范围不可

相交,求那个最小半径的最大值(每种策略的最小半径不同)。思:最优解:必然是选择的点最近

的俩个距离/2,其他半径大小无纺,不妨设他们都为该最小半径。求最小值最大,二分答案,每次判定

R是否可行,可行就往大的搜索,注意精度r-l<10^-4才可过。该题不需要输出方案,只需判定是否矛盾的

点在同一个SCC中即可。*/

#include<iostream>  //G++ 343ms,/c++,898ms 不知道为神马。。。求解释。。
#include<cstdio>
#include<cstring>
#include<vector>
#include<stack>
#include<cmath>
using namespace std;
int n;const int MAX=201;
struct points //点,01,23,45.。。相连为一对,x^1取对应点(改变奇偶性)
{
int x,y;
};
points point[MAX];
int low[MAX];int dfn[MAX];int visited[MAX];bool is_instack[MAX];stack<int>s;
int times=0; int scc[MAX]; int numblock;
vector<vector<int> >edges(MAX); //原图
void initialize() //初始化要注意!看哪里新建图,新遍历了。因为它耽误了好久!
{
numblock=times=0;
for(int i=0;i<2*n;i++)
{
visited[i]=low[i]=dfn[i]=is_instack[i]=0;
edges[i].clear();
scc[i]=-1;
}
}
void tarjan(int u) //有向图dfs,这个不解释
{
low[u]=dfn[u]=++times;
is_instack[u]=1;
s.push(u);
int len=edges[u].size();
for(int i=0;i<len;i++)
{
int v=edges[u][i];
if(visited[v]==0)
{
visited[v]=1;
tarjan(v);
if(low[u]>low[v])low[u]=low[v];
}
else if(is_instack[v]&&dfn[v]<low[u])
{
low[u]=dfn[v];
}
}
if(dfn[u]==low[u])
{
numblock++;
int cur;
do
{
cur=s.top();
is_instack[cur]=0;
s.pop();
scc[cur]=numblock;
}while(cur!=u);
}
}
double dis(points a,points b) //距离的平方,比较平方即可(据说更精准)。
{
double temp=(a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);
return (temp);
}
bool check(double r)
{
initialize(); //哪里初始化很重要!
for(int i=0;i<2*n;i++) //根据r建图
for(int j=i+1;j<2*n;j++)
{
if(((i>>1)!=(j>>1))&&dis(point[i],point[j])<4*r*r) //这里的读入很妙(学来的),等价偶数枚举其大2之后的,奇数枚举其后(比他大1)所有
{
edges[i].push_back(j^1);
edges[j].push_back(i^1);
}
}
for(int i=0;i<2*n;i++)
{
if(visited[i]==0)
{
visited[i]=1;
tarjan(i);
}
}
for(int i=0;i<2*n;i+=2)
{
if(scc[i]==scc[i+1]) //矛盾的点在一个SCC中,
{
return false;
}
}
return true;
}
void readin()
{
for(int i=0;i<n;i++)
{
scanf("%d%d%d%d",&point[i*2].x,&point[i*2].y,&point[i*2+1].x,&point[i*2+1].y);
}
}
int main()
{
while(~scanf("%d",&n))
{
readin();
double r;double left=0,right=10001,mid;
while(right-left>0.0001) //二分答案!
{
mid=(right+left)/2;
if(check(mid))
{
left=mid;
}
else
{
right=mid;
}
}
printf("%.2f\n",left);
}
}

最新文章

  1. SQL Server-聚焦使用索引和查询执行计划(五)
  2. Front End Developer Questions 前端开发人员问题(三)JavaScript部分
  3. Oracle数据库的SQL分页模板
  4. [Python] 学习笔记之MySQL数据库操作
  5. Onethink1.1 钩子和插件的使用!
  6. 不可或缺 Windows Native (15) - C++: 命名空间
  7. JAVA 正则表达式、汉字正则、 java正则代码
  8. 一、JSP、Servlet 概要
  9. 在代码中创建Drawable资源
  10. hdu2993坡dp+二进制搜索
  11. leetcode第19题--Remove Nth Node From End of List
  12. Python3基础 当函数中的局部变量与全局变量同名了,各管各的
  13. PAT1012
  14. EXAMPLE FOR PEEWEE 多姿势使用 PEEWEE
  15. Appium基础(四)查找app的appActivity与appPackage
  16. CyclicBarrier簡介
  17. 使用libcurl开源库和Duilib做的下载文件并显示进度条的小工具
  18. JAVA中MD5加密实现
  19. 【codevs3160】 LCS 【后缀自动机】
  20. 达梦数据库(DaMeng)如何删除IDENTITY自增属性字段

热门文章

  1. 清理xcode缓存
  2. knockout Observable Array(监控数组)
  3. Python——集合与字典练习
  4. 批量下载ts视频文件
  5. 收集的WEB前端程序员需要的网站整理
  6. 关于DTCC数据库技术大会
  7. Spring上传报错413
  8. VW结合rem进行移动端布局
  9. P2756 网络流解决二分图最大匹配
  10. URAL1966 Cipher Message 3