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
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\n",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\n",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 }