Matrix-Tree定理,用来解决生成树计数问题。
1、G的度数矩阵D[G]是一个n*n的矩阵,当i!=j时,D[i][j]=0;否则等于第i个点的度数。
2、G的邻接矩阵A[G],相连即为1,否则为0.
3、Kirchhof矩阵C[G]=D[G]-A[G]
4、Matrix-Tree定理:G的所有不同的生成树的个数等于Kirchhof矩阵的n-1阶行列式的值。
5、运用高斯消元求得行列式的值。
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int oo=333;
const int MOD=10007;
int x[oo],y[oo];
int g[oo][oo],dd[oo];
int equ,var;
int dist(int x1,int y1,int x2,int y2)
{
return (x1-x2)*(x1-x2)+(y1-y2)*(y1-y2);
}
int abs1(int num)
{
if(num>0) return num;
else return -1*num;
}
int gcd(int a,int b)
{
int t;
while(b!=0)
{
t=b;
b=a%b;
a=t;
}
return a;
}
int lcm(int a,int b)
{
return a*b/gcd(a,b);
}
void swap(int &a,int &b)
{
int tmp=a;a=b;b=tmp;
}
int gauss(int r, int c)//高斯消元求行列式值的模板
{
bool flag = false;
int coe = 1;
int i=0, t=0;
for(int j=0; j<c; ++j)
{
int index = i;
for(int k=i; k<r; ++k)
{
if(g[k][j] > 0)
{
index = k;
break;
}
}
if(g[index][j])
{
if(index != i)
{
for(int k=j; k<c; ++k)
{
swap(g[i][k], g[index][k]);
}
flag = !flag;
}
for(int k=i+1; k<r; ++k)
{
if(g[k][j])
{
coe = (coe * g[i][j]) % MOD;
++ t;
for(int l=c-1; l>=j; --l)
{
g[k][l] = (g[k][l] * g[i][j] - g[i][l] * g[k][j]) % MOD;
if(g[k][l] < 0)
{
g[k][l] += MOD;
}
}
}
}
++ i;
}
}
for(i=1;i<MOD;++i)
{
if((coe * i) % MOD == 1)
{
break;
}
}
int result = i;
for(i=0; i<r; ++i)
{
result = (result * g[i][i]) % MOD;
}
if(flag)
{
result = MOD - result;
}
return result;
}
int main()
{
//freopen("D:\\data.in","r",stdin);
//freopen("D:\\data.out","w",stdout);
int t,n,r,i,j,k,dis;
long long ans;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&r);
for(i=0;i<n;i++)
scanf("%d%d",&x[i],&y[i]);
memset(g,0,sizeof(g));
memset(dd,0,sizeof(dd));
for(i=0;i<n;i++)
for(j=i+1;j<n;j++)
{
if(dist(x[i],y[i],x[j],y[j])<=r*r)
{
g[i][j]=1;
g[j][i]=1;
for(k=0;k<n;k++)
{
if(k==i||k==j) continue;
if(x[k] > min(x[i], x[j]) && x[k] < max(x[i], x[j]) && (x[k] - x[i]) * (y[j] - y[i]) == (x[j] - x[i]) * (y[k] - y[i]))
{
{
g[i][j]=g[j][i]=0;
break;
}
}
}
}
}
for(int i=0; i<n; ++i)
{
for(int j=i+1; j<n; ++j)
{
if(g[i][j])
{
++ g[i][i];
++ g[j][j];
g[i][j] = g[j][i] = MOD - 1;
}
}
}
var=equ=n-1;
ans=gauss(n-1,n-1);
/* for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
cout<<g[i][j]<<" ";
cout<<endl;
}*/
if(ans==0) printf("-1\n");
else printf("%d\n",ans);
}
return 0;
}