DLx
Posted 既然选择了远方,便只顾风雨兼程
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了DLx相关的知识,希望对你有一定的参考价值。
1 #include <iostream>
2 #include <cstring>
3 #include <cstdio>
4 #include <cmath>
5 using namespace std;
6 const double eps=1e-8;
7 const int N=55,M=3005;
8 struct Point{int x,y;}c[N],r[N];
9 double sqr(double x){return 1.0*x*x;}
10 double dis(Point a,Point b){return sqrt(sqr(a.x-b.x)+sqr(a.y-b.y));}
11 int T,n,m,k,col[M],row[M];
12 int U[M],D[M],L[M],R[M];
13 int H[N],C[N],vis[N],cnt;
14 struct DLX{
15 void Init(int n,int m){
16 for(int i=0;i<=m;i++){
17 L[i]=i-1;R[i]=i+1;
18 C[i]=0;U[i]=D[i]=i;
19 }L[0]=m;R[m]=0;cnt=m;
20 for(int i=1;i<=n;i++)H[i]=0;
21 }
22 void Link(int r,int c){
23 C[c]+=1;++cnt;
24 U[D[c]]=cnt;U[cnt]=c;
25 D[cnt]=D[c];D[c]=cnt;
26 row[cnt]=r;col[cnt]=c;
27
28 if(H[r]){
29 L[R[H[r]]]=cnt;L[cnt]=H[r];
30 R[cnt]=R[H[r]];R[H[r]]=cnt;
31 }
32 else H[r]=L[cnt]=R[cnt]=cnt;
33 }
34 void Delete(int x){
35 for(int i=D[x];i!=x;i=D[i])
36 L[R[i]]=L[i],R[L[i]]=R[i];
37 }
38 void Resume(int x){
39 for(int i=U[x];i!=x;i=U[i])
40 L[R[i]]=i,R[L[i]]=i;
41 }
42 int F(){
43 int ret=0;
44 for(int c=R[0];c;c=R[c])vis[c]=0;
45 for(int c=R[0];c;c=R[c]){
46 if(vis[c])continue;ret+=1;
47 for(int i=D[c];i!=c;i=D[i])
48 for(int j=R[i];j!=i;j=R[j])
49 vis[col[j]]=1;vis[c]=1;
50 }
51 return ret;
52 }
53 bool Dance(int dep){
54 if(!R[0])return dep<=k;
55 if(dep+F()>k)return false;
56 int p=0;
57 for(int i=R[0];i;i=R[i])
58 if(!p||C[i]<C[p])p=i;
59 for(int i=D[p];i!=p;i=D[i]){
60 Delete(i);
61 for(int j=R[i];j!=i;j=R[j])Delete(j);
62 if(Dance(dep+1))return true;
63 for(int j=L[i];j!=i;j=L[j])Resume(j);
64 Resume(i);
65 }
66 return false;
67 }
68
69 bool Check(double d){
70 Init(m,n);
71 for(int i=1;i<=m;i++)
72 for(int j=1;j<=n;j++)
73 if(d>=dis(r[i],c[j]))
74 Link(i,j);
75 return Dance(0);
76 }
77 }dlx;
78
79 int main(){
80 scanf("%d",&T);
81 while(T--){
82 scanf("%d%d%d",&n,&m,&k);
83 for(int i=1;i<=n;i++)
84 scanf("%d%d",&c[i].x,&c[i].y);
85 for(int i=1;i<=m;i++)
86 scanf("%d%d",&r[i].x,&r[i].y);
87 double l=0,r=1e3;
88 while(r-l>=eps){
89 double mid=(l+r)/2;
90 if(dlx.Check(mid))r=mid;
91 else l=mid;
92 }
93 printf("%.6f\n",l);
94 }
95 return 0;
96 }
以上是关于DLx的主要内容,如果未能解决你的问题,请参考以下文章
[DLX精确覆盖+打表] hdu 2518 Dominoes
[DLX精确覆盖] hdu 1603 A Puzzling Problem