hdu 3622 bomb game

hdu 3622 bomb game
two_sat
N组,每组2个坐标,选择一个放置炸弹
,范围为半径为ri的圆 要求是任意的
两个圆不能相交,N小于等于100 最后的
得分是N个圆的最小半径 现在求的是最大
得分容易想到二分答案 并进行可行性分析
那么算法就有了。
1:确定上下界、
2:二分
3:判断是否可行
4:在精度范围内则跳出

最终二分的解就是答案

 #include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<sstream>
#include<string>
#include<climits>
#include<stack>
#include<set>
#include<bitset>
#include<cmath>
#include<deque>
#include<map>
#include<queue>
#define iinf 2000000000
#define linf 1000000000000000000LL
#define dinf 1e200
#define eps 1e-11
#define all(v) (v).begin(),(v).end()
#define sz(x)  x.size()
#define pb push_back
#define mp make_pair
#define lng long long
#define sqr(a) ((a)*(a))
#define pii pair<int,int>
#define pll pair<lng,lng>
#define pss pair<string,string>
#define pdd pair<double,double>
#define X first
#define Y second
#define pi 3.14159265359
#define ff(i,xi,n) for(int i=xi;i<=(int)(n);++i)
#define ffd(i,xi,n) for(int i=xi;i>=(int)(n);--i)
#define ffl(i,r) for(int i=head[r];i!=-1;i=edge[i].next)
#define cc(i,j) memset(i,j,sizeof(i))
#define two(x)			((lng)1<<(x))
#define N 500
#define M 1000000
#define lson l , mid , rt << 1
#define rson mid + 1 , r , rt << 1 | 1
#define Mod  n
#define Pmod(x) (x%Mod+Mod)%Mod
using namespace std;
typedef vector<int>  vi;
typedef vector<string>  vs;
typedef unsigned int uint;
typedef unsigned lng ulng;
template<class T> inline void checkmax(T &x,T y){if(x<y) x=y;}
template<class T> inline void checkmin(T &x,T y){if(x>y) x=y;}
template<class T> inline T Min(T x,T y){return (x>y?y:x);}
template<class T> inline T Max(T x,T y){return (x<y?y:x);}
template<class T> T gcd(T a,T  b){return (a%b)==0?b:gcd(b,a%b);}
template<class T> T lcm(T a,T b){return a*b/gcd(a,b);}
template<class T> T Abs(T a){return a>0?a:(-a);}
template<class T> inline T lowbit(T n){return (n^(n-1))&n;}
template<class T> inline int countbit(T n){return (n==0)?0:(1+countbit(n&(n-1)));}
template<class T> inline bool isPrimeNumber(T n)
{if(n<=1)return false;for (T i=2;i*i<=n;i++) if (n%i==0) return false;return true;}
template<class T> inline T Minmin(T a,T b,T c,T d){return Min(Min(a,b),Min(c,d));}
struct tarjan_seg
{
    int head[N],tot,id[N],pre[N],low[N],stack[N],top,n,m,Index,newid,newhead[N],*cur;
    struct pp
   {
        int v,next;
    }edge[N*N];
    void add(int u,int v)
    {
        edge[tot].v=v;
        edge[tot].next=cur[u];
        cur[u]=tot++;
    }
    void init()
    {
        cc(head,-1);
        tot=0;
        newid=0;
        cur=head;
        cc(pre,-1);
        cc(low,-1);
        top=0;
        cc(id,-1);
        Index=0;
    }
    void tarjan(int r,int p)
    {
        bool xx=false;
        pre[r]=low[r]=++Index;
        stack[++top]=r;
        ffl(i,r)
        {
            int v=edge[i].v;
            if(v==p&&xx==0)
            {
                xx=1;
                continue;
            }
            if(pre[v]==-1)
            {
                tarjan(v,r);
                checkmin(low[r],low[v]);
            }
            else
            if(id[v]==-1)
            checkmin(low[r],pre[v]);
        }
        if(pre[r]==low[r])
        {
            int v;
            ++newid;
            do
            {
                v=stack[top--];
                id[v]=newid;
            }while(v!=r);
        }
    }
    void solve()
    {
        ff(i,1,n)
        if(pre[i]==-1)
        tarjan(i,-1);
    }
    void build_map()
    {
        int  hash[N]={};
        cur=newhead;
        ff(i,1,n)
        {
            ffl(j,i)
            {
                int v=edge[j].v;
                if(id[i]!=id[v]&&hash[id[i]]!=id[j])
                add(id[i],id[j]),hash[id[i]]=id[j];
            }
        }
    }
    bool two_sat()
    {
        for(int i=1;i<=n;i+=2)
        if(id[i]==id[i+1])
        return false;
        return true;
    }
};
int nround;
int  x[N],y[N];
double dis[N][N];
double Distance(int i,int j)
{
    return sqrt((double)sqr(x[j]-x[i])+(double)sqr(y[j]-y[i]));
}
 tarjan_seg G;
bool check(double r)
{

    G.n=2*nround;
    G.init();
    ff(i,1,2*nround)
    ff(j,1,2*nround)
    {
        int u=(i+1)/2,v=(j+1)/2;
        if(v==u) continue;
        if(dis[i][j]<=2*r)
        G.add(i,4*v-1-j),G.add(j,4*u-1-i);
    }
    G.solve();
    return G.two_sat();
}
int main()
{
    while(scanf("%d",&nround)==1)
    {
        ff(i,1,2*nround)
        {
            scanf("%d%d",&x[i],&y[i]);
        }
        double le=0,ri=-100000,mid;
        ff(i,1,2*nround)
        ff(j,i+1,2*nround)
        {
            if((i+1)/2==(j+1)/2) continue;
            dis[i][j]=dis[j][i]=Distance(i,j);
            checkmax(ri,dis[i][j]);
        }
        while(ri-le>=eps)
        {
            mid=(le+ri)/2;
            if(check(mid))
          le=mid;
          else
          ri=mid;
        }
        printf("%.2f\n",Max(le,ri));
    }
    return 0;
}

  

你可能感兴趣的:(c,算法,struct,Build,distance)