zoukankan      html  css  js  c++  java
  • [2-sat]HDOJ3622 Bomb Game

    题意:给n对炸弹,每对炸弹选其中一个爆炸。

    每个炸弹爆炸的半径相同 圆不能相交, 求最大半径

    2-sat简介

    二分半径, 枚举n*2个炸弹

    若i炸弹与j炸弹的距离小于半径*2 则建边

    比如  第一对炸弹的第一个 与 第二对炸弹的第一个 距离小于半径*2

        则 建立 第一对炸弹的第一个$Rightarrow $第二对炸弹的第二个 、第二对炸弹的第一个$Rightarrow $第一对炸弹的第二个

    然后 通过判断能否取到n个炸弹 来判断 能否取该半径

      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 typedef long long LL;
      4 typedef pair<double, double> PI;
      5 const double eps=1e-6;
      6 #define INF 0x3f3f3f3f
      7 
      8 const int N=105*2;
      9 const int M=N*N;
     10 //注意n是拆点后的大小 即 n <<= 1 N为点数(注意要翻倍) M为边数 i&1=0为i真 i&1=1为i假
     11 struct Edge
     12 {
     13     int to, nex;
     14 }edge[M];
     15 //注意 N M 要修改
     16 int head[N], edgenum;
     17 void addedge(int u, int v)
     18 {
     19     Edge E={v, head[u]};
     20     edge[edgenum]=E;
     21     head[u]=edgenum++;
     22 }
     23 
     24 bool mark[N];
     25 int Stack[N], top;
     26 void init()
     27 {
     28     memset(head, -1, sizeof(head));
     29     edgenum=0;
     30     memset(mark, 0, sizeof(mark));
     31 }
     32 
     33 bool dfs(int x)
     34 {
     35     if(mark[x^1])
     36         return false;//一定是拆点的点先判断
     37     if(mark[x])
     38         return true;
     39     mark[x]=true;
     40     Stack[top++]=x;
     41     for(int i=head[x];i!=-1;i=edge[i].nex)
     42         if(!dfs(edge[i].to))
     43             return false;
     44     return true;
     45 }
     46 
     47 bool solve(int n)
     48 {
     49     for(int i=0;i<n;i+=2)
     50         if(!mark[i] && !mark[i^1])
     51         {
     52             top=0;
     53             if(!dfs(i))
     54             {
     55                 while(top)
     56                     mark[Stack[--top]]=false;
     57                 if(!dfs(i^1))
     58                     return false;
     59             }
     60         }
     61     return true;
     62 }
     63 
     64 PI a[205];
     65 double dis(PI a, PI b)
     66 {
     67     return sqrt((a.first-b.first)*(a.first-b.first)+(a.second-b.second)*(a.second-b.second));
     68 }
     69 
     70 int main()
     71 {
     72     int n;
     73     while(~scanf("%d", &n))
     74     {
     75         for(int i=0;i<n;i++)
     76         {
     77             double x1, y1, x2, y2;
     78             scanf("%lf%lf%lf%lf", &x1, &y1, &x2, &y2);
     79             a[i*2]=make_pair(x1, y1);
     80             a[i*2+1]=make_pair(x2, y2);
     81         }
     82         double l=0, r=15000;
     83         while(r-l>=eps)
     84         {
     85             double m=(l+r)/2.0;
     86             init();
     87             for(int i=0;i<n*2;i++)
     88                 for(int j=i+1+!(i&1);j<2*n;j++)
     89                     if(dis(a[i], a[j])<2*m)
     90                     {
     91                         addedge(i, j^1);
     92                         addedge(j, i^1);
     93                     }
     94             if(solve(n*2))
     95                 l=m;
     96             else
     97                 r=m;
     98         }
     99         printf("%.2f
    ", r);
    100     }
    101     return 0;
    102 }
    HDOJ 3622
  • 相关阅读:
    C#将datatable生成easyui的绑定tree 的json数据格式
    asp.net DataTable转JSON
    asp.net面试题
    windows笔记线程的一些性质
    windows笔记创建线程的另一个函数_beginthreadex
    windows笔记【内核对象线程同步】等待定时器内核对象
    windows笔记用哪个创建线程CreateThread还是_beginthread
    windows笔记【内核对象线程同步】信标内核对象
    windows笔记【内核对象线程同步】事件内核对象
    windows笔记【内核对象线程同步】等待函数
  • 原文地址:https://www.cnblogs.com/Empress/p/4738720.html
Copyright © 2011-2022 走看看