先用半平面交构出V图 然后连边bfs一通最短路
一个点的控制范围是和其他点的中垂线组成的半平面交
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<vector>
#include<cstring>
#define cl(x) memset(x,0,sizeof(x))
using namespace std;
inline int sgn(double a){
if (fabs(a)<1e-8) return 0; if (a<0) return -1; return 1;
}
const int N=605;
const double PI=acos(-1.0);
struct P{
double x,y;
void read() { scanf("%lf%lf",&x,&y); }
P(double x=0,double y=0):x(x),y(y) { }
P rot(double A){ return P(x*cos(A)-y*sin(A),x*sin(A)+y*cos(A)); }
double dist(){ return sqrt(x*x+y*y); }
friend P operator + (P A,P B) { return P(A.x+B.x,A.y+B.y); }
friend P operator - (P A,P B) { return P(A.x-B.x,A.y-B.y); }
friend double operator * (P A,P B) { return A.x*B.y-B.x*A.y; }
friend P operator * (P A,double B) { return P(A.x*B,A.y*B); }
friend P operator / (P A,double B) { return P(A.x/B,A.y/B); }
friend double dist(P A,P B){ return (A-B).dist(); }
}p[N];
struct Tl{
P p1,p2; int idx; double ang;
Tl() { }
Tl(P _p1,P _p2,int id) { p1=_p1; p2=_p2; idx=id; ang=atan2(p2.y-p1.y,p2.x-p1.x); }
friend bool operator < (const Tl &A,const Tl &B){
return sgn(A.ang-B.ang)==0?sgn((A.p1-B.p1)*(B.p2-B.p1))<0:sgn(A.ang-B.ang)<0;
}
friend P cross(const Tl &A,const Tl &B){
double ta=(A.p2-B.p1)*(A.p1-B.p1),tb=(A.p1-B.p2)*(A.p2-B.p2);
return (B.p1*tb+B.p2*ta)/(ta+tb);
}
}L[N]; int tot;
inline bool onleft(Tl& l1,Tl &l2,Tl &l3){
P tp=cross(l1,l2); return sgn((tp-l3.p1)*(l3.p2-l3.p1))<=0;
}
vector<int> G[N];
int Q[N],l,r;
inline bool hpi(int x){
sort(L+1,L+tot+1);
int pnt=1;
for (int i=2;i<=tot;i++) if (sgn(L[i].ang-L[i-1].ang)!=0) L[++pnt]=L[i];
tot=pnt;
l=1,r=0; Q[++r]=1;
for (int i=2;i<=tot;i++){
while (l<r && !onleft(L[Q[r-1]],L[Q[r]],L[i])) r--;
while (l<r && !onleft(L[Q[l]],L[Q[l+1]],L[i])) l++;
Q[++r]=i;
}
while (l<r && !onleft(L[Q[r-1]],L[Q[r]],L[Q[l]])) r--;
while (l<r && !onleft(L[Q[l]],L[Q[l+1]],L[Q[r]])) l++;
if (r-l<2) return 0;
for (int i=l;i<=r;i++)
G[x].push_back(L[Q[i]].idx);
return 1;
}
int n;
double xx,yy;
inline void work(int x){
tot=0;
L[++tot]=Tl(P(0,0),P(xx,0),n+1);
L[++tot]=Tl(P(xx,0),P(xx,yy),n+1);
L[++tot]=Tl(P(xx,yy),P(0,yy),n+1);
L[++tot]=Tl(P(0,yy),P(0,0),n+1);
for (int i=1;i<=n;i++){
if (i==x) continue;
P p1=(p[i]+p[x])/2.0,d=(p[i]-p[x]).rot(PI/2),p2=p1+d;
L[++tot]=Tl(p1,p2,i);
}
hpi(x);
}
int dis[N];
#define V G[u][i]
inline int bfs(int S){
static int Q[N],l,r;
l=r=-1; cl(dis); Q[++r]=S; dis[S]=1;
while (l<r){
int u=Q[++l];
for (int i=0;i<(int)G[u].size();i++)
if (!dis[V])
dis[V]=dis[u]+1,Q[++r]=V;
}
return dis[n+1]-1;
}
int main(){
int Q; P st;
freopen("t.in","r",stdin);
freopen("t.out","w",stdout);
scanf("%d",&Q);
while (Q--){
scanf("%d%lf%lf",&n,&xx,&yy);
st.read();
for (int i=1;i<=n;i++) p[i].read(),G[i].clear();
for (int i=1;i<=n;i++) work(i);
int S=1; double tmp=dist(p[1],st);
for (int i=2;i<=n;i++)
if (dist(p[i],st)<tmp)
tmp=dist(p[i],st),S=i;
printf("%d\n",bfs(S));
}
return 0;
}