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

 题目大意:

有一堆雷达工作站,安放至多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)