此博客是指一类2-sat的题目,需要通过二分,将答案不断精确化判断是否存在解来得出最临近临界值的解,具体见题。
题目:http://acm.hdu.edu.cn/showproblem.php?pid=3622
题意:一个人在玩游戏,这个游戏的规则是每次给两个点x1,y1,x2,y2,每次只能选择其中的一个点,然后以所有选择的点为圆心做同样大小的圆,这些圆可以相切,但不可以相交,求圆半径的最大值。
输入说明:输入n,代表要输入多少对点,接下来n行,输入4个数,分别代表x1,y1,x2,y2;
题解:通过二分半径,log2(最大半径)的复杂度,不断求临界值,当左右差满足省略条件时输出
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<vector>
#include<cmath>
using namespace std;
typedef struct
{
double x,y;
}Node;
Node node[250];
const int MAX=5555;
int dfn[MAX],low[MAX],belong[MAX],time;
int cont;
bool instack[MAX];
int _stack[MAX],top;
vector<int> dian[MAX];
void tarjan(int root)
{
dfn[root]=low[root]=time++;
_stack[top++]=root;
instack[root]=true;
for(int i=0;i<dian[root].size();i++)
{
int son=dian[root][i];
if(!dfn[son])
{
tarjan(son);
low[root]=min(low[root],low[son]);
}
else if(instack[son])
{
low[root]=min(low[root],dfn