题目链接:hdu 2295 Radar
题意:
给你n个城市,m个雷达,现在最多用K个雷达,求最小半径覆盖全部的城市。
题解:
二分半径套一个DLX就行。网上随便找的一个板子
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #include<bits/stdc++.h> 2 #define F(i,a,b) for(int i=a;i<=b;++i) 3 using namespace std; 4 const double eps=1e-7; 5 6 struct Point{ 7 double x,y; 8 }city[100],radar[100]; 9 double dis[55][55]; 10 double dist(Point a,Point b){ 11 double s=a.x-b.x,t=a.y-b.y; 12 return s*s+t*t; 13 } 14 15 int K; 16 17 struct DLX{ 18 const static int mn=20010; 19 #define FF(i,A,s) for(int i=A[s];i!=s;i=A[i]) 20 #define INF 0x3f3f3f3f 21 int L[mn],R[mn],U[mn],D[mn]; 22 int size,col[mn],row[mn],s[mn],H[mn]; 23 bool vis[70]; 24 int ans[mn],cnt; 25 void init(int m){ 26 F(i,0,m)L[i]=i-1,R[i]=i+1,U[i]=D[i]=i,s[i]=0; 27 memset(H,-1,sizeof(H)); 28 L[0]=m;R[m]=0;size=m+1; 29 } 30 void link(int r,int c){ 31 U[size]=c;D[size]=D[c];U[D[c]]=size;D[c]=size; 32 if(H[r]<0)H[r]=L[size]=R[size]=size; 33 else L[size]=H[r],R[size]=R[H[r]],L[R[H[r]]]=size,R[H[r]]=size; 34 s[c]++,col[size]=c,row[size]=r,size++; 35 } 36 void del(int c){ 37 L[R[c]]=L[c];R[L[c]]=R[c]; 38 FF(i,D,c)FF(j,R,i)U[D[j]]=U[j],D[U[j]]=D[j],--s[col[j]]; 39 } 40 void add(int c){ 41 R[L[c]]=L[R[c]]=c; 42 FF(i,U,c)FF(j,L,i)++s[col[U[D[j]]=D[U[j]]=j]]; 43 } 44 bool dfs(int k){//精确覆盖 45 if(!R[0]){ 46 cnt=k;return 1; 47 } 48 int c=R[0];FF(i,R,0)if(s[c]>s[i])c=i; 49 del(c); 50 FF(i,D,c){ 51 FF(j,R,i)del(col[j]); 52 ans[k]=row[i];if(dfs(k+1))return 1; 53 FF(j,L,i)add(col[j]); 54 } 55 add(c); 56 return 0; 57 } 58 void remove(int c){FF(i,D,c)L[R[i]]=L[i],R[L[i]]=R[i];}//重复覆盖 59 void resume(int c){FF(i,U,c)L[R[i]]=R[L[i]]=i;} 60 int A(){//估价函数 61 int res=0; 62 memset(vis,0,sizeof(vis)); 63 FF(i,R,0)if(!vis[i]){ 64 res++;vis[i]=1; 65 FF(j,D,i)FF(k,R,j)vis[col[k]]=1; 66 } 67 return res; 68 } 69 void dfs(int now,int &ans){//重复覆盖 70 if(R[0]==0)ans=min(ans,now); 71 else if(now+A()<ans){ 72 int temp=INF,c; 73 FF(i,R,0)if(temp>s[i])temp=s[i],c=i; 74 FF(i,D,c){ 75 remove(i);FF(j,R,i)remove(j); 76 dfs(now+1,ans); 77 FF(j,L,i)resume(j);resume(i); 78 } 79 } 80 } 81 }dlx; 82 83 int main() 84 { 85 int t,n,m; 86 scanf("%d",&t); 87 while(t--){ 88 scanf("%d%d%d",&n,&m,&K); 89 for(int i=1;i<=n;i++)scanf("%lf%lf",&city[i].x,&city[i].y); 90 for(int i=1;i<=m;i++)scanf("%lf%lf",&radar[i].x,&radar[i].y); 91 F(i,1,m)F(j,1,n)dis[i][j]=dist(radar[i],city[j]); 92 double l=0,r=1000; 93 while(r-l>eps){ 94 double mid=(l+r)/2,ss=mid*mid; 95 dlx.init(n); 96 F(i,1,m)F(j,1,n)if(dis[i][j]<=ss)dlx.link(i,j); 97 int ans=INF; 98 dlx.dfs(0,ans); 99 if(ans>K)l=mid;else r=mid; 100 } 101 printf("%.6f\n",l); 102 } 103 return 0; 104 }