DLX + 二分半徑
double的二分判斷???
#include<cstdio>
#include <iostream>
#include <vector>
#include <cstring>
#include <algorithm>
#include <math.h>
using namespace std;
const int maxn = 55 * 55;
const int maxr = 55;
const int maxc = 55;
int U[maxn],D[maxn],L[maxn],R[maxn],C[maxn];
int H[maxr],S[maxc];
bool v[maxc];
int sz,ans;
///行編號從1開始,列編號爲1~c,結點0爲表頭結點
///注意給行和列的編號
///注意sz,ans.要自己初始化和賦值!!!
void init(int r,int c)///傳入行列數
{
for(int i=0; i<=c; ++i)
{
S[i]=0;
D[i]=U[i]=i;
L[i+1]=i;
R[i]=i+1;
}
R[c]=0;
while(r)H[r--]=-1;
}
int geth()//??
{
int ret=0;
for(int c=R[0]; c; c=R[c]) v[c]=1;
for(int c=R[0]; c; c=R[c]) if(v[c])
{
v[c]=0, ++ret;
for(int i=D[c]; i!=c; i=D[i])
for(int 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])
R[L[i]]=R[i],L[R[i]]=L[i];
}
void resume(int c)
{
for(int i=U[c]; i!=c; i=U[i])
R[L[i]]=L[R[i]]=i;
}
void Dance(int d)///第一次調用傳入0
{
if(d+geth()>=ans)return;
if(!R[0])
{
ans=d;
return;
}
// int c = R[0];
// for (i = R[0]; i; i = R[i])
// if (S[i] < R[c]) c = i;
int c = R[0], tmp = S[R[0]];
for (int i = R[R[0]]; i; i = R[i])
if (S[i] < tmp) tmp = S[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);
Dance(d+1);
for(int j=L[i]; j!=i; j=L[j])resume(j);
resume(i);
}
}
void Link(int r,int c)
{
++S[C[++sz]=c];
D[sz]=D[c];
U[D[c]]=sz;
U[sz]=c;
D[c]=sz;
if(H[r]<0)H[r]=L[sz]=R[sz]=sz;
else
{
R[sz]=R[H[r]];
L[R[H[r]]]=sz;
L[sz]=H[r];
R[H[r]]=sz;
}
}
struct Point{
double x, y;
void read()
{
scanf("%lf%lf", &x, &y);
}
};
Point city[55];
Point radar[55];
int T, N, M, K;
const double eps = 1e-8;
int dcmp(double x)
{
if (fabs(x) < eps) return 0;
if (x < 0) return -1;
else return 1;
}
#define sqr(x) (x) * (x)
void add(int x, double r)
{
// cout << x + 1 << " : " << endl;
for (int i = 0; i < N; i++)
{
// cout << sqrt(sqr(city[i].x - radar[x].x) + sqr(city[i].y - radar[x].y)) << ' ' << r << endl;
if (dcmp(sqrt(sqr(city[i].x - radar[x].x) + sqr(city[i].y - radar[x].y)) - r) <= 0)
{
// cout << i + 1<< endl;
Link(x + 1, i + 1);
}
}
}
bool test(double r)
{
init(M, N);
sz = N;///!!!
for (int i = 0; i < M; i++) add(i, r);
ans = M + 1;///!!!
Dance(0);
// cout << ans << endl;
return ans <= K;
}
int main()
{
scanf("%d", &T);
int nn, mm;
while(T--)
{
scanf("%d%d%d", &N, &M, &K);
for (int i = 0; i < N; i++) city[i].read();
for (int i = 0; i < M; i++) radar[i].read();
double l = 0.0, r = 1000000.0;
while (l + eps <= r)
{
double m = (l + r) / 2;
if (test(m)) r = m;
else l = m;
}
printf("%.6lf\n", l);
}
return 0;
}