hdu 2295 dlx重复覆盖+二分答案
2015-05-16 23:10
399 查看
题目大意:
有一堆雷达工作站,安放至多k个人在这些工作站中,找到一个最小的雷达监控半径可以使k个工作人所在的雷达工作站覆盖所有城市
二分半径的答案,每次利用dlx的重复覆盖来判断这个答案是否正确
有一堆雷达工作站,安放至多k个人在这些工作站中,找到一个最小的雷达监控半径可以使k个工作人所在的雷达工作站覆盖所有城市
二分半径的答案,每次利用dlx的重复覆盖来判断这个答案是否正确
#include <iostream> #include <cstring> #include <cstdio> #include <algorithm> #include <queue> #include <climits> #include <cmath> using namespace std; #define N 55 #define MAXNODE 3000 const double INF = 1e9; const double eps = 1e-8; int n,m,k; struct DLX{ int n,m,size; int U[MAXNODE] , D[MAXNODE] , L[MAXNODE] , R[MAXNODE]; int col[MAXNODE] , row[MAXNODE]; int first , cnt_col ; bool v[MAXNODE]; void init(int _n , int _m) { n = _n , m = _m , size = _m; for(int i=0 ; i<=m ; i++){ U[i] = D[i] = i; L[i] = i-1 , R[i] = i+1; col[i] = i , row[i] = 0; } L[0] = m , R[m] = 0; for(int i=1 ; i<=n ; i++) first[i] = -1; for(int i=1 ; i<=m ; i++) cnt_col[i] = 0; } void link(int r , int c) { ++size; U[D[c]] = size , D[size] = D[c]; U[size] = c , D[c] = size; cnt_col[c]++; if(first[r]<0) first[r] = L[size] = R[size] = size; else{ R[size] = R[first[r]] , L[R[first[r]]] = size; L[size] = first[r] , R[first[r]] = size; } row[size] = r , col[size] = c; } void Remove(int c) { for(int i=D[c] ; i!=c ; i=D[i]){ L[R[i]] = L[i] , R[L[i]] = R[i]; } } void Resume(int c) { for(int i=U[c] ; i!=c ; i=U[i]){ L[R[i]] = R[L[i]] = i; } } int f() { int ret = 0; for(int c=R[0] ; c!=0 ; c=R[c]) v[c]=true; for(int c=R[0] ; c!=0 ; c=R[c]) if(v[c]){ ret++; v[c] = false; for(int i=D[c] ; i!=c ; i=D[i]) for(int j=R[i] ; j!= i ; j=R[j]) v[col[j]]=false; } return ret; } bool Dance(int d) { //这里k表示题目所给意思让我们至多在dlx中选择k行 if(d+f() > k) return false; if(!R[0]) return d<=k; int st = R[0]; for(int i=R[0] ; i!=0 ; i=R[i]) if(cnt_col[st]>cnt_col[i]) st=i; for(int i=D[st] ; i!=st ; i=D[i]){ Remove(i); for(int j=R[i] ; j!=i ; j=R[j]) Remove(j); if(Dance(d+1)) return true; for(int j=L[i] ; j!=i ; j=L[j]) Resume(j); Resume(i); } return false; } }dlx; struct Point{ double x,y; }p1 , p2 ; double getDis(int i , int j) { 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)); } bool check(double mid) { dlx.init(m , n); for(int i=1 ; i<=m ; i++){ for(int j=1; j<=n ;j++){ if(getDis(j , i)<=mid) dlx.link(i,j); } } return dlx.Dance(0); } double bin_search() { double l=0 , r=INF; while(r-l>eps){ double mid = (l+r)/2; if(check(mid)) r=mid; else l=mid; } return r; } int main() { // freopen("a.in" , "r" , stdin); int T; scanf("%d" , &T); while(T--) { scanf("%d%d%d" , &n , &m , &k); for(int i=1 ; i<=n ; i++) scanf("%lf%lf" , &p1[i].x , &p1[i].y); for(int i=1 ; i<=m ; i++) scanf("%lf%lf" , &p2[i].x , &p2[i].y); printf("%.6lf\n" , bin_search()); } return 0; }
相关文章推荐
- HDU 2295 Radar(二分+DLX重复覆盖)
- hdu 2295 Radar (二分答案+重复覆盖)
- hdu 2295 Radar(重复覆盖,二分+DLX)
- [ACM] HDU 2295 Radar (二分+DLX 重复覆盖)
- HDU 2295 Radar (DLX可重复覆盖+二分)
- HDU 2295 Radar (二分+DLX,重复覆盖)
- hdu 2295 Radar 重复覆盖 DLX+二分答案 给出一些城市及一些雷达的坐标,要求从这些雷达中选取最多k个能够覆盖所有的城市,问雷达的最小覆盖半径为多少
- HDU 5046 Airport (DLX可重复覆盖+二分)
- 【HDU】2295 Radar 二分+重复覆盖
- HDU 2295 Radar(DLX可重复覆盖)
- HDU 2295 Radar (二分 + Dancing Links 重复覆盖模型 )
- HDU-5046 Airport(二分+DLX重复覆盖)
- HDU 2295 Radar(重复覆盖,DLX)
- HDU 2295 Radar【二分+Dancing Links重复覆盖】
- HDU 5046 Airport(二分+DLX重复覆盖)
- 搜索(DLX重复覆盖模板):HDU 2295 Radar
- HDU_2295_Radar(DancingLinksX重复覆盖+二分)
- HDU 2295 Radar(二分+重复覆盖)
- hdu 2295 DLX重复覆盖
- (中等) HDU 5046 Airport ,DLX+可重复覆盖+二分。