首页 > 代码库 > hdu 2295 Radar(二分+DLX)

hdu 2295 Radar(二分+DLX)

题目链接:hdu 2295 Radar

题意:

给你n个城市,m个雷达,现在最多用K个雷达,求最小半径覆盖全部的城市。

题解:

二分半径套一个DLX就行。网上随便找的一个板子

技术分享
  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 }
View Code

 

hdu 2295 Radar(二分+DLX)