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

hdu 2295 dlx重复覆盖+二分答案

时间:2015-05-17 00:42:17      阅读:175      评论:0      收藏:0      [点我收藏+]

标签:

 题目大意:

有一堆雷达工作站,安放至多k个人在这些工作站中,找到一个最小的雷达监控半径可以使k个工作人所在的雷达工作站覆盖所有城市

 

二分半径的答案,每次利用dlx的重复覆盖来判断这个答案是否正确

  1 #include <iostream>
  2 #include <cstring>
  3 #include <cstdio>
  4 #include <algorithm>
  5 #include <queue>
  6 #include <climits>
  7 #include <cmath>
  8 
  9 using namespace std;
 10 #define N 55
 11 #define MAXNODE 3000
 12 const double INF = 1e9;
 13 const double eps = 1e-8;
 14 
 15 int n,m,k;
 16 
 17 struct DLX{
 18     int n,m,size;
 19     int U[MAXNODE] , D[MAXNODE] , L[MAXNODE] , R[MAXNODE];
 20     int col[MAXNODE] , row[MAXNODE];
 21     int first[N] , cnt_col[N];
 22     bool v[MAXNODE];
 23 
 24     void init(int _n , int _m)
 25     {
 26         n = _n , m = _m , size = _m;
 27         for(int i=0 ; i<=m ; i++){
 28             U[i] = D[i] = i;
 29             L[i] = i-1 , R[i] = i+1;
 30             col[i] = i , row[i] = 0;
 31         }
 32         L[0] = m , R[m] = 0;
 33         for(int i=1 ; i<=n ; i++) first[i] = -1;
 34         for(int i=1 ; i<=m ; i++) cnt_col[i] = 0;
 35     }
 36 
 37     void link(int r , int c)
 38     {
 39         ++size;
 40         U[D[c]] = size , D[size] = D[c];
 41         U[size] = c , D[c] = size;
 42         cnt_col[c]++;
 43 
 44         if(first[r]<0) first[r] = L[size] = R[size] = size;
 45         else{
 46             R[size] = R[first[r]] , L[R[first[r]]] = size;
 47             L[size] = first[r] , R[first[r]] = size;
 48         }
 49         row[size] = r , col[size] = c;
 50     }
 51 
 52     void Remove(int c)
 53     {
 54         for(int i=D[c] ; i!=c ; i=D[i]){
 55             L[R[i]] = L[i] , R[L[i]] = R[i];
 56         }
 57     }
 58 
 59     void Resume(int c)
 60     {
 61         for(int i=U[c] ; i!=c ; i=U[i]){
 62             L[R[i]] = R[L[i]] = i;
 63         }
 64     }
 65 
 66     int f()
 67     {
 68         int ret = 0;
 69         for(int c=R[0] ; c!=0 ; c=R[c]) v[c]=true;
 70         for(int c=R[0] ; c!=0 ; c=R[c])
 71             if(v[c]){
 72                 ret++;
 73                 v[c] = false;
 74                 for(int i=D[c] ; i!=c ; i=D[i])
 75                     for(int j=R[i] ; j!= i ; j=R[j])
 76                         v[col[j]]=false;
 77             }
 78         return ret;
 79     }
 80 
 81     bool Dance(int d)
 82     {
 83         //这里k表示题目所给意思让我们至多在dlx中选择k行
 84         if(d+f() > k) return false;
 85         if(!R[0]) return d<=k;
 86         int st = R[0];
 87         for(int i=R[0] ; i!=0 ; i=R[i])
 88             if(cnt_col[st]>cnt_col[i]) st=i;
 89 
 90         for(int i=D[st] ; i!=st ; i=D[i]){
 91             Remove(i);
 92             for(int j=R[i] ; j!=i ; j=R[j]) Remove(j);
 93             if(Dance(d+1)) return true;
 94             for(int j=L[i] ; j!=i ; j=L[j]) Resume(j);
 95             Resume(i);
 96         }
 97         return false;
 98     }
 99 }dlx;
100 
101 struct Point{
102     double x,y;
103 }p1[N] , p2[N];
104 
105 double getDis(int i , int j)
106 {
107     return sqrt((p1[i].x-p2[j].x)*(p1[i].x-p2[j].x)+(p1[i].y-p2[j].y)*(p1[i].y-p2[j].y));
108 }
109 
110 bool check(double mid)
111 {
112     dlx.init(m , n);
113     for(int i=1 ; i<=m ; i++){
114         for(int j=1; j<=n ;j++){
115             if(getDis(j , i)<=mid) dlx.link(i,j);
116         }
117     }
118     return dlx.Dance(0);
119 }
120 
121 double bin_search()
122 {
123     double l=0 , r=INF;
124     while(r-l>eps){
125         double mid = (l+r)/2;
126         if(check(mid)) r=mid;
127         else l=mid;
128     }
129     return r;
130 }
131 
132 int main()
133 {
134    // freopen("a.in" , "r" , stdin);
135     int T;
136     scanf("%d" , &T);
137     while(T--)
138     {
139         scanf("%d%d%d" , &n , &m , &k);
140         for(int i=1 ; i<=n ; i++)
141             scanf("%lf%lf" , &p1[i].x , &p1[i].y);
142         for(int i=1 ; i<=m ; i++)
143             scanf("%lf%lf" , &p2[i].x , &p2[i].y);
144         printf("%.6lf\n" , bin_search());
145     }
146     return 0;
147 }

 

hdu 2295 dlx重复覆盖+二分答案

标签:

原文地址:http://www.cnblogs.com/CSU3901130321/p/4508882.html

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