http://acm.hdu.edu.cn/showproblem.php?pid=4305
题意:距离小于r可以联通,但是中间不能被挡住。
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn =305;
const ll mode =1e4+7;
struct node{
int x,y;
}p[306];
bool checksame(node a,node b,node c){
if(b.x<min(a.x,c.x)||b.x>max(a.x,c.x))return false;
if(b.y<min(a.y,c.y)||b.y>max(a.y,c.y))return false;
if(((a.x-c.x)*(c.y-b.y))!=((c.x-b.x)*(a.y-c.y)))return false;
return true;
}
ll a[305][305];
ll det(int n){
int i,j,k;
ll ans=1;
for(i=0;i<n;i++){
for(j=i+1;j<n;j++){
while(a[j][i]){
ll tmp=a[i][i]/a[j][i];
for(k=0;k<n;k++){
a[i][k]=((a[i][k]-a[j][k]*tmp)%mode+mode)%mode;
swap(a[i][k],a[j][k]);
}
ans= -ans;
}
}
if(a[i][i]==0)return -1;
ans=ans*a[i][i]%mode;
}
return (ans%mode+mode)%mode;
}
int n;
ll r;
int len(node a,node b){
return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);
}
int g[maxn][maxn];
int main(){
//freopen("1","r",stdin);
int t,i,j,k;
scanf("%d",&t);
while(t--){
memset(a,0,sizeof(a));
memset(g,0,sizeof(g));
scanf("%d%lld",&n,&r);
r=r*r;
//printf("%lld\n",r);
for(i=0;i<n;i++)scanf("%d%d",&p[i].x,&p[i].y);
for(i=0;i<n;i++){
for(j=0;j<n;j++){
if(i==j)continue;
if(len(p[i],p[j])>r)continue;
for(k=0;k<n;k++){
if(k==i||k==j)continue;
if(checksame(p[i],p[k],p[j]))break;
}
if(k==n)g[i][j]=1;
}
}
//for(i=0;i<n;i++){for(j=0;j<n;j++)printf("%d ",g[i][j]);putchar('\n');}
for(i=0;i<n;i++){
for(j=0;j<n;j++)if(g[i][j]&&i!=j){
a[i][i]++;
a[i][j]=-1;
}
}
ll ans=det(n-1);
printf("%lld\n",ans);
}
return 0;
}