zoukankan      html  css  js  c++  java
  • hdu3622:Bomb Game

    给n<=100对点,从每对点里面挑一个并以这些挑出的点为圆心画圆,并且这些圆不能互相覆盖,找出一种方案使得这些圆半径中最小的那个最大。

    “最小值最大”就是二分答案啦!考虑现在每个点都画出半径x的圆,如何选点呢?

    可以发现选了一个点P之后与其距离相差2x内的点Q都不能被选,也就是“与P在同一对的另一个点P'    或    与Q在同一对的另一个点Q'”

    有了或语句描述选点冲突,接下来就是2-SAT构图啦!

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<algorithm>
      4 #include<cstdlib>
      5 #include<cmath>
      6 //#include<iostream>
      7 using namespace std;
      8 
      9 int n;
     10 #define maxn 111*2
     11 struct Edge{int to,next;};
     12 #define maxe maxn*maxn
     13 struct Graph
     14 {
     15     Edge edge[maxe];int le;
     16     int first[maxn],vis[maxn];
     17     void clear()
     18     {
     19         le=2;
     20         memset(first,0,sizeof(first));
     21     }
     22     void insert(int x,int y)
     23     {
     24         edge[le].to=y;
     25         edge[le].next=first[x];
     26         first[x]=le++;
     27     }
     28     void add_clause(int x,int y)
     29     {
     30         insert(x^1,y);
     31         insert(y^1,x);
     32     }
     33     int sta[maxn],top;
     34     bool dfs(int x)
     35     {
     36         if (vis[x^1]) return 0;
     37         if (vis[x]) return 1;
     38         vis[x]=1;
     39         sta[++top]=x;
     40         for (int i=first[x];i;i=edge[i].next)
     41             if (!dfs(edge[i].to)) return 0;
     42         return 1;
     43     }
     44     bool twosat()
     45     {
     46         memset(vis,0,sizeof(vis));
     47         for (int i=1;i<=n;i++)
     48             if (!vis[i*2] && !vis[i*2+1])
     49             {
     50                 top=0;
     51                 if (!dfs(i*2))
     52                 {
     53                     for (;top;top--) vis[sta[top]]=0;
     54                     if (!dfs(i*2+1)) return 0;
     55                 }
     56             }
     57         return 1;
     58     }
     59 }G;
     60 struct Point
     61 {
     62     int x,y;
     63 }a[maxn];
     64 double dis[maxn][maxn];
     65 #define eps 1e-5
     66 double sqr(double x) {return x*x;}
     67 double caldis(int p,int q)
     68 {
     69     return sqrt(sqr(a[p].x-a[q].x)+sqr(a[p].y-a[q].y));
     70 }
     71 bool judge(double x)
     72 {
     73     for (int i=1;i<=n;i++)
     74         for (int j=i+1;j<=n;j++)
     75         {
     76             if (dis[i*2][j*2]<x*2) G.add_clause(i*2+1,j*2+1);
     77             if (dis[i*2+1][j*2]<x*2) G.add_clause(i*2,j*2+1);
     78             if (dis[i*2][j*2+1]<x*2) G.add_clause(i*2+1,j*2);
     79             if (dis[i*2+1][j*2+1]<x*2) G.add_clause(i*2,j*2);
     80         }
     81     return G.twosat();
     82 }
     83 int main()
     84 {
     85     while (~scanf("%d",&n))
     86     {
     87         for (int i=1;i<=n;i++)
     88             scanf("%d%d%d%d",&a[i*2].x,&a[i*2].y,&a[i*2+1].x,&a[i*2+1].y);
     89         double L=0.0,R=0.0;
     90         for (int i=2;i<=n*2+1;i++)
     91             for (int j=2;j<=n*2+1;j++)
     92                 dis[i][j]=caldis(i,j),R=max(R,dis[i][j]);
     93         while (R-L>=eps)
     94         {
     95             G.clear();
     96             double mid=(L+R+eps)/2;
     97             if (judge(mid)) L=mid;
     98             else R=mid-eps;
     99         }
    100         printf("%.2lf
    ",L);
    101     }
    102     return 0;
    103 }
    View Code
  • 相关阅读:
    现代程序设计——homework-01
    数据结构 学习笔记03——栈与队列
    MCI 函数与命令
    mciSendString用法
    VC6.0 error LNK2001: unresolved external symbol _main解决办法
    数据结构 学习笔记02——线性表
    数据结构 学习笔记01
    《windows程序设计》学习_4:文本输出,加滚动条
    浅析指针(pointer)与引用(reference)
    指针数组 | 数组指针
  • 原文地址:https://www.cnblogs.com/Blue233333/p/7209920.html
Copyright © 2011-2022 走看看