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
1 3 3 2 3 4 3 1 5 4 1 1 2 2 3 3
2.236068
Source: The 4th Baidu Cup Central China Invitational Programming Contest
题目:http://acm.tju.edu.cn/acm/showp3219.html
hdu上一样的题:http://acm.hdu.edu.cn/showproblem.php?pid=2295
分析:这题很明显可以转化为取最少的雷达,使得所有的城市都被覆盖,可以重复覆盖,只要二分半径,敲个重复覆盖的DLX。。。
最近眼力不行了,读入写错,找了一个小时。。。
代码:
#include<cstdio> #define mm 3333 #define mn 55 #define dis(a,b) ((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)) struct place{int x,y;}city[mn],radar[mn]; int U[mm],D[mm],L[mm],R[mm],C[mm]; int H[mn],S[mn],d[mn][mn]; bool v[mn]; int m,n,K,size; void prepare(int r,int c) { for(int i=0;i<=c;++i) { S[i]=0; U[i]=D[i]=i; L[i+1]=i; R[i]=i+1; } R[c]=0; size=c; while(r)H[r--]=-1; } int f() { int i,j,c,ret=0; for(c=R[0];c;c=R[c])v[c]=1; for(c=R[0];c;c=R[c]) if(v[c])for(++ret,v[c]=0,i=D[c];i!=c;i=D[i]) for(j=R[i];j!=i;j=R[j])v[C[j]]=0; return ret; } 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 Dance(int k) { if(k+f()>K)return 0; if(!R[0])return(k<=K); int i,j,c,tmp=mm; for(i=R[0];i;i=R[i]) if(S[i]<tmp)tmp=S[c=i]; for(i=D[c];i!=c;i=D[i]) { remove(i); for(j=R[i];j!=i;j=R[j])remove(j); if(Dance(k+1))return 1; for(j=L[i];j!=i;j=L[j])resume(j); resume(i); } return 0; } void Link(int r,int c) { ++S[C[++size]=c]; D[size]=D[c]; U[D[c]]=size; U[size]=c; D[c]=size; if(H[r]<0)H[r]=L[size]=R[size]=size; else { R[size]=R[H[r]]; L[R[H[r]]]=size; L[size]=H[r]; R[H[r]]=size; } } int main() { int i,j,T; scanf("%d",&T); while(T--) { scanf("%d%d%d",&n,&m,&K); for(i=1;i<=n;++i)scanf("%d%d",&city[i].x,&city[i].y); for(i=1;i<=m;++i)scanf("%d%d",&radar[i].x,&radar[i].y); double l=0,r=0,cur; for(i=1;i<=m;++i) for(j=1;j<=n;++j) { d[i][j]=dis(radar[i],city[j]); if(d[i][j]>r)r=d[i][j]; } while(r-l>1e-7) { cur=(l+r)/2.0; prepare(m,n); for(i=1;i<=m;++i) for(j=1;j<=n;++j) if(d[i][j]<=cur*cur)Link(i,j); if(Dance(0))r=cur; else l=cur; } printf("%.6lf\n",l); } return 0; }