HDU 2295 Radar (DLX + 二分)

Radar

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2882    Accepted Submission(s): 1113


Problem Description
N cities of the Java Kingdom need to be covered by radars for being in a state of war. Since the kingdom has M radar stations but only K operators, we can at most operate K radars. All radars have the same circular coverage with a radius of R. Our goal is to minimize R while covering the entire city with no more than K radars.
 
Input
The input consists of several test cases. The first line of the input consists of an integer T, indicating the number of test cases. The first line of each test case consists of 3 integers: N, M, K, representing the number of cities, the number of radar stations and the number of operators. Each of the following N lines consists of the coordinate of a city.
Each of the last M lines consists of the coordinate of a radar station.

All coordinates are separated by one space.
Technical Specification

1. 1 ≤ T ≤ 20
2. 1 ≤ N, M ≤ 50
3. 1 ≤ K ≤ M
4. 0 ≤ X, Y ≤ 1000
 
Output
For each test case, output the radius on a single line, rounded to six fractional digits.
 
Sample Input
1 3 3 2 3 4 3 1 5 4 1 1 2 2 3 3
 
Sample Output
2.236068
 
 
 
 
昨天用G++交T了一下午,刚才换C++交了一发报RE了,发现是数组开小了,改后重交就过了,早知道是RE昨天就不会那么头疼了,再也不信G++。
用二分来找答案,城市作为列,每个雷达最为行,行和列的组合就是此雷达能否覆盖这个城市,每次给出一个二分数值后构造一个矩阵,然后dancing一下,如果能得到答案那么将值减小再尝试,反之加大。
  1 #include <iostream>
  2 #include <cstdlib>
  3 #include <cstring>
  4 #include <algorithm>
  5 #include <cstdlib>
  6 #include <cmath>
  7 #include <cstdio>
  8 using    namespace    std;
  9 
 10 struct    Node
 11 {
 12     double    x,y;
 13 };
 14 
 15 const    int    HEAD = 0;
 16 const    int    SIZE = 55;
 17 int    N,M,K;
 18 double    RADAR[SIZE][SIZE];
 19 Node    CITY[SIZE];
 20 bool    VIS[SIZE];
 21 int    U[SIZE * SIZE],D[SIZE * SIZE],L[SIZE * SIZE],R[SIZE * SIZE],C[SIZE * SIZE],S[SIZE * SIZE];
 22 
 23 int    comp(const void * a,const void * b);
 24 int    h(void);
 25 void    debug(int count);
 26 void    ini(void);
 27 bool    dancing(int);
 28 void    remove(int);
 29 void    resume(int);
 30 
 31 int    main(void)
 32 {
 33     int    t;
 34     double    x,y;
 35 
 36     scanf("%d",&t);
 37     while(t --)
 38     {
 39         scanf("%d%d%d",&N,&M,&K);
 40         for(int i = 0;i < N;i ++)
 41             scanf("%lf%lf",&CITY[i].x,&CITY[i].y);
 42         for(int i = 0;i < M;i ++)
 43         {
 44             scanf("%lf%lf",&x,&y);
 45             for(int j = 0;j < N;j ++)
 46                 RADAR[i][j] = sqrt(pow(CITY[j].x - x,2) + pow(CITY[j].y - y,2));
 47         }
 48 
 49         double    l = 0,r = 1500;
 50         double    mid = 0;
 51         while(r - l > 1e-7)
 52         {
 53             mid = (l + r) / 2;
 54             ini();
 55 
 56             int    count = N + 1;
 57             for(int i = 0;i < M;i ++)
 58             {
 59                 int    first = count;
 60                 for(int j = 0;j < N;j ++)
 61                     if(RADAR[i][j] <= mid)
 62                     {
 63                         R[count] = count + 1;
 64                         L[count] = count - 1;
 65                         U[count] = U[j + 1];
 66                         D[count] = j + 1;
 67 
 68                         D[U[j + 1]] = count;
 69                         U[j + 1] = count;
 70 
 71                         C[count] = j + 1;
 72                         S[j + 1] ++;
 73                         count ++;
 74                     }
 75                 L[first] = count - 1;
 76                 if(first != count)
 77                     R[count - 1] = first;
 78             }
 79             //debug(count );
 80             if(dancing(0))
 81                 r = mid;
 82             else    
 83                 l = mid;
 84         }
 85 
 86         printf("%lf
",mid);
 87     }
 88 
 89     return    0;
 90 }
 91 
 92 void    ini(void)
 93 {
 94     R[HEAD] = 1;
 95     L[HEAD] = N;
 96     for(int i = 1;i <= N;i ++)
 97     {
 98         L[i] = i - 1;
 99         R[i] = i + 1;
100         U[i] = D[i] = C[i] = i;
101         S[i] = 0;
102     }
103     R[N] = HEAD;
104 }
105 
106 bool    dancing(int k)
107 {
108     if(R[HEAD] == HEAD)
109         return    true;
110     if(k + h() > K)
111         return    false;
112 
113     int    c = R[HEAD];
114     for(int i = R[HEAD];i != HEAD;i = R[i])
115         if(S[c] > S[i])
116             c = i;
117 
118     for(int i = D[c];i != c;i = D[i])
119     {
120         remove(i);
121         for(int j = R[i];j != i;j = R[j])
122             remove(j);
123         if(dancing(k + 1))
124             return    true;
125         for(int j = L[i];j != i;j = L[j])
126             resume(j);
127         resume(i);
128     }
129 
130     return    false;
131 }
132 
133 void    remove(int c)
134 {
135     for(int i = D[c];i != c;i = D[i])
136     {
137         L[R[i]] = L[i];
138         R[L[i]] = R[i];
139     }
140 }
141 
142 void    resume(int c)
143 {
144     for(int i = D[c];i != c;i = D[i])
145     {
146         L[R[i]] = i;
147         R[L[i]] = i;
148     }
149 }
150 
151 void    debug(int count)
152 {
153     for(int i = 0;i < count;i ++)
154         printf("%d U:%d D:%d L:%d R:%d C:%d S:%d
",i,U[i],D[i],L[i],R[i],C[i],S[i]);
155     cout << endl << endl;
156 }
157 
158 int    h(void)
159 {
160     fill(VIS,VIS + SIZE,false);
161     
162     int    count = 0;
163     for(int i = R[HEAD];i;i = R[i])
164         if(!VIS[i])
165         {
166             count ++;
167             VIS[i] = true;
168             for(int j = D[i];j != i;j = D[j])
169                 for(int k = R[j];k != j;k = R[k])
170                     VIS[C[k]] = true;
171         }
172     return    count;
173 }
原文地址:https://www.cnblogs.com/xz816111/p/4432095.html