建图我是用的极角排序,然后枚举建图。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<utility>
using namespace std;
const double eps=1e-8;
const double inf=1e10;
const int maxn=305;
const int mod=10007;
struct pos
{
double first,second;
int id;
};
int Sign(double x)
{
return x<-eps?-1:x>eps;
}
double Fabs(double x)
{
return (Sign(x)<0)?-x:(x>eps?x:0);
}
double multi(pos p0,pos p1,pos p2)
{
pos v1,v2;
v1.first=p1.first-p0.first;
v1.second=p1.second-p0.second;
v2.first=p2.first-p0.first;
v2.second=p2.second-p0.second;
return v1.first*v2.second-v1.second*v2.first;
}
double dist(pos p1,pos p2)
{
return sqrt(pow(p1.first-p2.first,2)+pow(p1.second-p2.second,2));
}
//*****************************Work*******************
pos p[maxn],tp[maxn];
int Cnt[maxn];
//double C[maxn][maxn];
int C[maxn][maxn];
bool hash[maxn];
bool cmp(pos p1,pos p2)
{
pos v1,v2;
double k=multi(p[0],p1,p2);
if(Sign(k)==-1)
return 1;
else if(Sign(k)==0)
{
if(Sign(p[0].first-p1.first)==0&&Sign(p[0].first-p2.first)==0)
{
if(Sign(p[0].second-p1.second)*Sign(p[0].second-p2.second)<0)
return Sign(p[0].second-p1.second)>0;
else
return dist(p[0],p1)<dist(p[0],p2);
}
if(Sign(p[0].first-p1.first)*Sign(p[0].first-p2.first)<0)
{
return Sign(p[0].first-p1.first)>0;
}
else
{
return dist(p[0],p1)<dist(p[0],p2);
}
}
else
return 0;
}
void swap(int i,int j)
{
pos tmp;
tmp=p[j];
p[j]=p[i];
p[i]=tmp;
}
int exgcd(int a,int b,int &x,int &y)//乘法逆元返回的d是a,b的公约数,x是a mod b的逆元
{
if(b==0)
{
x=1;y=0;
return a;
}
int d=exgcd(b,a%b,x,y);
int t=x;
x=y;
y=t-a/b*y;
return d;
}
void Print(int n)
{
int i,j;
cout<<"*******************************************"<<endl;
for(i=0;i<n;++i)
{
for(j=0;j<n;++j)
{
cout<<" "<<C[i][j];
}
cout<<endl;
}
}
void init(int n,double r)
{
memset(Cnt,0,sizeof(Cnt));
memset(C,0,sizeof(C));
int i,j;
for(i=0;i<n;++i)
{
memcpy(p,tp,sizeof(tp));
swap(0,i);
sort(p+1,p+n,cmp);
// for(j=0;j<n;++j)
// cout<<'\t'<<p[j].id;
// cout<<'\t'<<Sign(multi(p[0],p[1],p[2]));
// cout<<endl;
for(j=1;j<n;++j)
{
if(Sign(dist(p[0],p[j])-r)==1)
continue;
if(j>1)
{
// cout<<"j==2"<<'\t'<<Sign(multi(p[0],p[j-1],p[j]))<<endl;
// cout<<Sign(p[0].first-p[j-1].first)<<'\t'<<Sign(p[0].first-p[j].first)<<endl;
if(Sign(multi(p[0],p[j-1],p[j]))==0)
{
if(Sign(p[0].first-p[j-1].first)==0&&Sign(p[0].first-p[j].first)==0)
{
if(Sign(p[0].second-p[j-1].second)*Sign(p[0].second-p[j].second)>0)
{
// cout<<"c1"<<endl;
continue;
}
}
else if(Sign(p[0].first-p[j-1].first)*Sign(p[0].first-p[j].first)>0)
{
// cout<<"c2"<<endl;
continue;
}
}
}
C[p[0].id][p[j].id]=C[p[j].id][p[0].id]=-1;
Cnt[p[0].id]++;Cnt[p[j].id]++;
}
}
for(i=0;i<n;++i)
{
C[i][i]=Cnt[i]/2;
}
// Print(n);
}
void dfs(int u,int n)
{
hash[u]=true;
int i,v;
for(i=0;i<n;++i)
{
if(C[u][i]==-1&&!hash[i])
dfs(i,n);
}
}
//double Det(int n) //化成下三角形式
//{
// double ret=1.0,tmp;
// int i,j,k,sign=0;
// for(i=0;i<n;++i)
// {
// for(j=i;j<n;++j)
// if(Sign(C[j][i])!=0)
// break;
// if(j==n)
// return 0.0;
// if(j!=i)
// sign++;
// for(k=0;k<n;++k)
// swap(C[i][k],C[j][k]);
Print(n);
// for(j=i+1;j<n;++j)
// {
// tmp=C[i][j]/C[i][i];
// for(k=i+1;k<n;++k)
// {
// C[k][j]-=tmp*C[k][i];
// }
// }
Print(n);
// }
// for(i=0;i<n;++i)
// ret*=C[i][i];
// if(sign&1)
// ret=-ret;
// return ret;
//}
int det(int n)//计算n阶行列式的绝对值 % mod
{
int ans=1;
int flag=1;//行列交换的次数
int i,j,k;
for(i=0;i<n;i++)
{
if(C[i][i]==0)
{
for(j=i+1;j<n;j++)
if(C[j][i])break;
if(j==n)return 0;//某列的值全是0的ans=0;
flag=!flag;
for(int k=i;k<n;k++)
swap(C[i][k],C[j][k]);//i和j行交换
}
ans=ans*C[i][i]%mod;//对角线相乘
int x,y;
int tp=exgcd(C[i][i],mod,x,y);//x为逆元
for(k=i+1;k<n;k++)
C[i][k]=C[i][k]*x%mod;
for(int j=i+1;j<n;j++)
for(int k=i+1;k<n;k++)
{
C[j][k]=(C[j][k]-C[j][i]*C[i][k])%mod;
if(j==k)
C[j][k]=(C[j][k]+mod)%mod;
}
}
ans=(ans%mod+mod)%mod;
if(flag) return ans;
else return mod-ans;
}
int main()
{
int t,n,r,i;
bool flag;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&r);
for(i=0;i<n;++i)
{
scanf("%lf%lf",&tp[i].first,&tp[i].second);
tp[i].id=i;
}
init(n,r*1.0);
memset(hash,false,sizeof(hash));
flag=true;
dfs(0,n);
for(i=0;i<n;++i)
if(hash[i]==false)
flag=false;
if(flag)
printf("%d\n",det(n-1));
else
printf("-1\n");
}
return 0;
}