hdu 3622 Bomb Game

来源:互联网 发布:galgame破解软件 编辑:程序博客网 时间:2024/06/05 15:24

在两个点中选一个点使以他们为圆心的形成的最小半径最大。

把任意两个点的距离求出来,把互斥的两个点设为最小。对距离进行二分,如果两个点距离小于当前二分的值,则把a-b'和b-a’连起来,判断可行。

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>#include <queue>using namespace std;#define eps 1e-5const int maxn=1005;const int maxm=200005;int head[maxn],next[maxm],to[maxm],h2[maxn];int dfn[maxn],low[maxn],stk[maxn],scc[maxn],ind[maxn],vis[maxn];int color[maxn],f[maxn];double gra[maxn][maxn];int tot,top,cnt,id;struct Point{    double x,y;}p[maxn];double dis(Point &n1,Point&n2){    return sqrt((n1.x-n2.x)*(n1.x-n2.x)+(n1.y-n2.y)*(n1.y-n2.y));}void addEdage(int u,int v){    next[tot]=head[u],to[tot]=v,head[u]=tot++;}void init(){    memset(head,-1,sizeof(head));    memset(vis,0,sizeof(vis));    memset(dfn,0,sizeof(dfn));    tot=top=cnt=0;}void tarjan(int v){    dfn[v]=low[v]=++cnt;    vis[v]=1;    stk[++top]=v;    for(int i=head[v];i!=-1;i=next[i])    {        int u=to[i];        if(!dfn[u])        {            tarjan(u);            low[v]=min(low[v],low[u]);        }        else if(vis[u])            low[v]=min(low[v],dfn[u]);    }    if(low[v]==dfn[v])    {        id++;        while(true)        {            int u=stk[top--];            vis[u]=0;            scc[u]=id;            if(u==v)break;        }    }}bool judge(double mid,int n){     init();     for(int i=0;i<2*n;i++)     {         for(int j=0;j<2*n;j++)         {             if(i/2!=j/2&&gra[i][j]-mid<eps)             {                addEdage(i,j^1);                addEdage(j,i^1);             }         }     }     for(int i=0;i<2*n;i++)     if(!dfn[i])tarjan(i);     for(int i=0;i<2*n;i+=2)     if(scc[i]==scc[i+1])     {         return 0;     }     return 1;}void solve(int n,double l,double r){    double mid;//    cout<<l<<" "<<r<<endl;    while(r-l>eps)    {        mid=(l+r)/2.0;        if(judge(mid,n))          l=mid;        else          r=mid;    }    printf("%.2lf\n",l/2.0);}int main(){    // freopen("in.txt","r",stdin);     int n;     while(~scanf("%d",&n))     {         memset(gra,0,sizeof(gra));         double l=0,r=0;         for(int i=0;i<n;i++)         {            scanf("%lf%lf%lf%lf",&p[2*i].x,&p[2*i].y,&p[2*i+1].x,&p[2*i+1].y);            for(int j=0;j<2*i;j++)            {                gra[2*i][j]=gra[j][2*i]=dis(p[2*i],p[j]);                gra[2*i+1][j]=gra[j][2*i+1]=dis(p[2*i+1],p[j]);                r=max(gra[2*i][j],r);                r=max(gra[2*i+1][j],r);            }         }         solve(n,l,r);     }     return 0;}


原创粉丝点击