题目是说 给了n个城市 m个雷达 你只能选择其中的k个雷达进行使用 你可以设置每个雷达的半径,最后使得所有城市都被覆盖,要求雷达的半径尽可能的小(所有雷达的半径是一样的)
二分最小半径,然后每次重新建立这个十字链表,跑dlx


#include <iostream> #include <cstdio> #include <algorithm> #include <string.h> #include <cmath> using namespace std; const int maxnode=3000; const int maxm=55; int K; struct DLX { int n,m,siz; int U[maxnode],D[maxnode],R[maxnode],L[maxnode],row[maxnode], col[maxnode]; int H[maxm],S[maxm]; int anss,ans[maxm]; void init(int n,int m) { this->n=n; this->m=m; for(int i=0; i<=n; i++) { S[i]=0; U[i]=D[i]=i; L[i]=i-1; R[i]=i+1; } R[n]=0; L[0]=n; siz=n+1; for(int i=0; i<=m; i++) H[i]=-1; } void Link(int r, int c) { row[siz]=r; col[siz]=c; S[c]++; D[siz]=c; U[siz]=U[c]; D[U[siz]]=siz; U[D[siz]]=siz; if(H[r]<0) { H[r]=L[siz]=R[siz]=siz; } else { L[siz]=H[r]; R[siz]=R[H[r]]; R[L[siz]]=siz; L[R[siz]]=siz; H[r]=siz; } siz++; } 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; } bool v[maxnode]; int AX() { 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) { if(d+AX()>K)return false; if(R[0]==0)return d<=K; int c=R[0]; for(int i=R[0]; i!=0; i=R[i]) if(S[i]<S[c])c=i; for(int i=D[c]; i!=c; 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; } }g; const double eps=1e-8; struct Point{ int x,y; void input() { scanf("%d%d",&x,&y); } }city[maxm],station[maxm]; double dis(Point a, Point b) { return sqrt((double)(a.x-b.x)*(a.x-b.x)+(double)(a.y-b.y)*(a.y-b.y)); } int main() { int T; int n,m; scanf("%d",&T); while(T--) { scanf("%d%d%d",&n,&m,&K); for(int i=0 ;i<n; i++)city[i].input(); for(int i=0; i<m; i++)station[i].input(); double l=0,r=1e8; while(r-l>=eps) { double mid=(l+r)/2; g.init(n,m); for(int i=0; i<m; i++) for(int j=0; j<n; j++) if(dis(station[i],city[j])<mid-eps) g.Link(i+1,j+1); if(g.Dance(0))r=mid-eps; else l=mid+eps; } printf("%.6lf\n",l); } return 0; }