码迷,mamicode.com
首页 > 其他好文 > 详细

Bomb Game

时间:2014-08-24 23:30:53      阅读:249      评论:0      收藏:0      [点我收藏+]

标签:style   blog   http   color   os   io   for   ar   art   

hdu3622:http://acm.hdu.edu.cn/showproblem.php?pid=3622

题意:你有n次,每次你可以在平面上放置一个点,并且每一次都会有两个位置可以选,每一次只能选择其中一个。然后在自己位置上以该点为圆心画圆,这n个圆不能相交,问你最后最小的圆的半径的最大值是多少。

题解:二分+2-sat。对于2-sat的建图始终很迷糊。这里的一次有两个点,并且每一次能选择其中一个,这就相当于把n个点弄成了2*n点。如果i--j距离太近 ,则建边i-->~j,j—>~i.

bubuko.com,布布扣
  1 #include<cstdio>
  2 #include<cstring>
  3 #include<algorithm>
  4 #include<iostream>
  5 #include<cmath>
  6 using namespace std;
  7 const int N=310;
  8 const int M=30010;
  9 const double eps=1e-4;
 10 struct Edge{
 11     int to,next;
 12 } edge[M];
 13 struct Node{
 14   double x;
 15   double y;
 16 }num1[600];
 17 int  n,m,cnt,dep,top,atype;
 18 int  dfn[N],low[N],vis[N],head[N],st[N],belong[N],in[N],out[N],sum[N];
 19 //sum[i]记录第i个连通图的点的个数,in[i],out[i],表示缩点之后点的入度和初度。
 20 void init(){
 21       cnt=dep=top=atype=0;
 22     memset(head,-1,sizeof(head));
 23     memset(dfn,0,sizeof(dfn));
 24     memset(low,0,sizeof(low));
 25     memset(vis,0,sizeof(vis));
 26     memset(belong,0,sizeof(belong));
 27     memset(in,0,sizeof(in));
 28     memset(out,0,sizeof(out));
 29     memset(sum,0,sizeof(sum));
 30 }
 31 void addedge(int u,int v){
 32     edge[cnt].to=v;
 33     edge[cnt].next=head[u];
 34     head[u]=cnt++;
 35 }
 36 
 37 void Tarjan(int u){
 38     dfn[u]=low[u]=++dep;
 39     st[top++]=u;
 40     vis[u]=1;
 41     for(int i=head[u]; i!=-1; i=edge[i].next){
 42         int v=edge[i].to;
 43         if(!dfn[v]){
 44             Tarjan(v);
 45             low[u]=min(low[u],low[v]);
 46         }
 47         else if(vis[v]){
 48             low[u]=min(low[u],dfn[v]);
 49         }
 50     }
 51     int j;
 52     if(dfn[u]==low[u]){
 53         atype++;
 54         do{
 55             j=st[--top];
 56             belong[j]=atype;
 57             sum[atype]++;   //记录每个连通分量中点的个数
 58             vis[j]=0;
 59         }
 60         while(u!=j);
 61     }
 62 }
 63 bool judge(double mid){
 64     init();
 65     //int base=2*n;
 66     for(int i=1;i<=2*n;i++){
 67         for(int j=i+1;j<=2*n;j++){
 68             double dis=sqrt((num1[i].x-num1[j].x)*(num1[i].x-num1[j].x)+(num1[i].y-num1[j].y)*(num1[i].y-num1[j].y));
 69             if(dis<2*mid){
 70                 if(i<=n&&j<=n){
 71                     addedge(i,j+n);
 72                     addedge(j,i+n);
 73                 }
 74                 if(i<=n&&j>n){
 75                     addedge(i,j-n);
 76                     addedge(j,i+n);
 77                 }
 78                 if(i>n&&j<=n){
 79                     addedge(i,j+n);
 80                     addedge(j,i-n);
 81                 }
 82                 if(i>n&&j>n){
 83                     addedge(i,j-n);
 84                     addedge(j,i-n);
 85                 }
 86 
 87             }
 88         }
 89     }
 90     for(int i=1;i<=2*n;i++)
 91       if(!dfn[i])Tarjan(i);
 92     for(int i=1;i<=n;i++)
 93        if(belong[i]==belong[i+n])
 94           return false;
 95 
 96   return true;
 97 
 98 }
 99 int main(){
100     while(~scanf("%d",&n)){
101         for(int i=1;i<=n;i++){
102         scanf("%lf %lf %lf %lf",&num1[i].x,&num1[i].y,&num1[i+n].x,&num1[i+n].y);
103         }
104         double l=0,r=10000,ans=0;
105         while(abs(l-r)>eps){
106             double mid=(l+r)/2.0;
107             if(judge(mid)){
108                 ans=mid;
109                 l=mid;
110             }
111             else{
112                 r=mid;
113             }
114         }
115         printf("%.2f\n",ans);
116     }
117 
118 }
View Code

 

Bomb Game

标签:style   blog   http   color   os   io   for   ar   art   

原文地址:http://www.cnblogs.com/chujian123/p/3933688.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!