#include <bits/stdc++.h> using namespace std; struct DLX { const static int maxn=64,maxm=64,maxnode=maxn*maxn; int n,m,sz,anssz; int u[maxnode],d[maxnode],l[maxnode],r[maxnode],row[maxnode],col[maxnode]; //row col 记录该节点i坐标 int h[maxn],colcnt[maxm]; void init(int _n,int _m) //数据位于1,1...n,m { n=_n,m=_m; for(int i=0;i<=m;i++)//1..m是每一列的辅助结点 0代表(0,0)即head { u[i]=d[i]=i; l[i]=i-1;r[i]=i+1; col[i]=i;row[i]=0; colcnt[i]=0; } l[0]=m;r[m]=0; sz=m;anssz=INT_MAX; for(int i=1;i<=n;i++)h[i]=-1; } void push(int x,int y) { colcnt[y]++; col[++sz]=y; row[sz]=x; d[sz]=d[y]; //加入列首元素后面 u[sz]=y; u[d[y]]=sz; d[y]=sz; if(h[x]<0) h[x]=r[sz]=l[sz]=sz; //成为行首元素 else{ int hd=h[x]; //加入行首节点右边 l[sz]=hd; r[sz]=r[hd]; l[r[hd]]=sz; r[hd]=sz; } } void repeat_remove(int x){ for(int i=d[x];i!=x;i=d[i]) l[r[i]]=l[i],r[l[i]]=r[i]; } void repeat_resume(int x){ for(int i=u[x];i!=x;i=u[i]) l[r[i]]=r[l[i]]=i; } int H(){ static bool vis[maxm]; memset(vis,0,sizeof vis); int res=0; for(int i=r[0];i!=0;i=r[i]){ //如果该列未被标标记,则标记该列中每行的列 if(vis[i]) continue; res++;vis[i]=1; for(int j=d[i];j!=i;j=d[j]) for(int k=r[j];k!=j;k=r[k]) vis[col[k]]=1; } return res;//易证res <= ans-dep } void repeat_dance(int dep) { if(r[0]==0){ anssz=min(anssz,dep); return ; } if(dep+H()>=anssz) return ; int cur=r[0]; for(int i=r[0];i!=0;i=r[i]) if(colcnt[i]<colcnt[cur])cur=i; // repeat_remove(cur); for(int i=d[cur];i!=cur;i=d[i]){ repeat_remove(i); for(int j=r[i];j!=i;j=r[j]) repeat_remove(j); repeat_dance(dep+1); for(int j=l[i];j!=i;j=l[j]) repeat_resume(j); repeat_resume(i); } // repeat_resume(cur); } }; DLX dlx; struct point{ double x,y; double dis(const point &a) { return hypot(a.x-x,a.y-y); } }; point city[64],radar[64]; bool le(double a,double b) { if(a<b)return true; } int main() { #ifdef shuaishuai freopen("in.txt","r",stdin); #endif // shuaishuai //二分裸重复覆盖 int t; scanf("%d",&t); while(t--) { int n,m,k; scanf("%d%d%d",&n,&m,&k); for(int i=0;i<n;i++)scanf("%lf%lf",&city[i].x,&city[i].y); for(int i=0;i<m;i++)scanf("%lf%lf",&radar[i].x,&radar[i].y); double l=0,r=2000; do{ double mi=(l+r)/2; static bool vis[64]; memset(vis,0,sizeof vis); int cnt=0; dlx.init(m,n); for(int i=0;i<m;i++)for(int j=0;j<n;j++) if(radar[i].dis(city[j])<=mi){ if(!vis[j]) vis[j]=true,cnt++; dlx.push(i+1,j+1); } if(cnt!=n) {l=mi;continue;} dlx.repeat_dance(0); if(dlx.anssz>k) l=mi; else r=mi; }while(r-l>1e-7); printf("%.6f\n",(l+r)/2); } return 0; }
hdu 2298 Radar 重复覆盖
猜你喜欢
转载自www.cnblogs.com/polya/p/9758224.html
今日推荐
周排行