HDU 3622 二分+2-sat

题意:一个游戏,共有n轮,每一轮给你两个圆的圆心,你只能在两个之间选择一个,然后你可以确定最大的直径,使得你所选择的任何两个圆之间没有公共面积。


分析:直接二分直径,跑2-sat,看看适不适合~


代码:

//O(m)求2-sat,此处下标从0开始
#pragma comment(linker,"/STACK:102400000,102400000")
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;
typedef long long ll;   //记得必要的时候改成无符号
const int maxn=6005;   //点数
const int maxm=2000005;   //边数
const int INF=1000000000;
struct EdgeNode
{
    int from;
    int to;
    int next;
}edge[maxm];
int head[maxn],cnt;
void add(int x,int y)
{
    edge[cnt].from=x;edge[cnt].to=y;edge[cnt].next=head[x];head[x]=cnt++;
    //printf("    %d %d\n",x,y);
}

void init()
{
    cnt=0;
    memset(head,-1,sizeof(head));
}

int dfn[maxn],low[maxn],ins[maxn],cixu,scc_count,n,ru[maxn],chu[maxn],sd[maxn];
stackS;

void dfs(int u)
{
    int v,x;
    dfn[u]=low[u]=++cixu;
    S.push(u);
    ins[u]=1;
    for(int i=head[u];i!=-1;i=edge[i].next)
    {
        v=edge[i].to;
        if(!dfn[v]){
            dfs(v);
            low[u]=min(low[u],low[v]);
        }
        else if(ins[v])
            low[u]=min(low[u],dfn[v]);
    }
    if(dfn[u]==low[u])
    {
        scc_count++;
        do
        {
            x=S.top();
            S.pop();
            sd[x]=scc_count;
            ins[x]=0;
        }while(x!=u);
    }
}

void tarjan()
{
    for(int i=0;i1e-6){
            mid=(l+r)/2;
            if(pd(mid))l=mid;
            else r=mid;
        }
        printf("%.2f\n",mid);
    }
    return 0;
}


你可能感兴趣的:(2-sat)