HDU-3622 Bomb Game 2sat

  题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3622

  题意:一个平面上有很多的炸弹,每个炸弹的爆炸范围是一样的,求最大的爆炸范围使得炸弹之间不相互影响。

  二分爆炸范围,然后建立2sat模型,看是否存在解。

  1 //STATUS:C++_AC_171MS_972KB
  2 #include <functional>
  3 #include <algorithm>
  4 #include <iostream>
  5 //#include <ext/rope>
  6 #include <fstream>
  7 #include <sstream>
  8 #include <iomanip>
  9 #include <numeric>
 10 #include <cstring>
 11 #include <cassert>
 12 #include <cstdio>
 13 #include <string>
 14 #include <vector>
 15 #include <bitset>
 16 #include <queue>
 17 #include <stack>
 18 #include <cmath>
 19 #include <ctime>
 20 #include <list>
 21 #include <set>
 22 #include <map>
 23 using namespace std;
 24 //using namespace __gnu_cxx;
 25 //define
 26 #define pii pair<int,int>
 27 #define mem(a,b) memset(a,b,sizeof(a))
 28 #define lson l,mid,rt<<1
 29 #define rson mid+1,r,rt<<1|1
 30 #define PI acos(-1.0)
 31 //typedef
 32 typedef long long LL;
 33 typedef unsigned long long ULL;
 34 //const
 35 const int N=210;
 36 const int INF=0x3f3f3f3f;
 37 const int MOD=5000,STA=100010;
 38 const LL LNF=1LL<<60;
 39 const double EPS=1e-8;
 40 const double OO=1e15;
 41 const int dx[4]={-1,0,1,0};
 42 const int dy[4]={0,1,0,-1};
 43 const int day[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
 44 //Daily Use ...
 45 inline int sign(double x){return (x>EPS)-(x<-EPS);}
 46 template<class T> T gcd(T a,T b){return b?gcd(b,a%b):a;}
 47 template<class T> T lcm(T a,T b){return a/gcd(a,b)*b;}
 48 template<class T> inline T lcm(T a,T b,T d){return a/d*b;}
 49 template<class T> inline T Min(T a,T b){return a<b?a:b;}
 50 template<class T> inline T Max(T a,T b){return a>b?a:b;}
 51 template<class T> inline T Min(T a,T b,T c){return min(min(a, b),c);}
 52 template<class T> inline T Max(T a,T b,T c){return max(max(a, b),c);}
 53 template<class T> inline T Min(T a,T b,T c,T d){return min(min(a, b),min(c,d));}
 54 template<class T> inline T Max(T a,T b,T c,T d){return max(max(a, b),max(c,d));}
 55 //End
 56 
 57 double d[N][N];
 58 int nod[N][2];
 59 int first[N],next[N*N*2],vis[N],S[N];
 60 int n,mt,cnt;
 61 
 62 struct Edge{
 63     int u,v;
 64 }e[N*N*2];
 65 
 66 double dist(int i,int j){
 67     return sqrt((double)((nod[i][0]-nod[j][0])*(nod[i][0]-nod[j][0])+
 68                 (nod[i][1]-nod[j][1])*(nod[i][1]-nod[j][1])));
 69 }
 70 
 71 void adde(int a,int b)
 72 {
 73     e[mt].u=a,e[mt].v=b;
 74     next[mt]=first[a];first[a]=mt++;
 75 }
 76 
 77 int dfs(int u)
 78 {
 79     if(vis[u^1])return 0;
 80     if(vis[u])return 1;
 81     int i;
 82     vis[u]=1;
 83     S[cnt++]=u;
 84     for(i=first[u];i!=-1;i=next[i]){
 85         if(!dfs(e[i].v))return 0;
 86     }
 87     return 1;
 88 }
 89 
 90 int Twosat()
 91 {
 92     int i,j;
 93     for(i=0;i<n;i+=2){
 94         if(vis[i] || vis[i^1])continue;
 95         cnt=0;
 96         if(!dfs(i)){
 97             while(cnt)vis[S[--cnt]]=0;
 98             if(!dfs(i^1))return 0;
 99         }
100     }
101     return 1;
102 }
103 
104 void init(double limt)
105 {
106     int i,j;
107     mt=0;mem(vis,0);
108     mem(first,-1);
109     for(i=0;i<n;i++){
110         for(j=i+2;j<n;j++)if(d[i][j]<limt)adde(i,j^1),adde(j,i^1);
111         i++;
112         for(j=i+1;j<n;j++)if(d[i][j]<limt)adde(i,j^1),adde(j,i^1);
113     }
114 }
115 
116 double binary(double l,double r)
117 {
118     double mid;
119     while(fabs(l-r)>EPS){
120         mid=(l+r)/2;
121      //   printf("%.2lf %.2lf %.2lf\n",l,r,mid);
122         init(mid);
123         if(Twosat())l=mid;
124         else r=mid;
125     }
126     return mid;
127 }
128 
129 int main()
130 {
131  //   freopen("in.txt","r",stdin);
132     int i,j;
133     double hig;
134     while(~scanf("%d",&n))
135     {
136         n<<=1;
137         for(i=0;i<n;i+=2){
138             scanf("%d%d%d%d",&nod[i][0],&nod[i][1],&nod[i^1][0],&nod[i^1][1]);
139         }
140         hig=0;
141         for(i=0;i<n;i++){
142             for(j=i+1;j<n;j++){
143                 d[i][j]=d[j][i]=dist(i,j);
144                 hig=Max(hig,d[i][j]);
145             }
146         }
147 
148         printf("%.2lf\n",binary(0,hig)/2);
149     }
150     return 0;
151 }

 

转载于:https://www.cnblogs.com/zhsl/p/3175914.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值