1. 程式人生 > >hdu4305生成樹計數

hdu4305生成樹計數

open assert with for def com false tor ==

先預處理出距離,然後判斷是否可行,要註意判斷是否在一條直線上時判斷是在兩側還是一邊(wa了四次)

double型數據

技術分享
#include<map>
#include<set>
#include<cmath>
#include<queue>
#include<stack>
#include<vector>
#include<cstdio>
#include<cassert>
#include<iomanip>
#include<cstdlib>
#include<cstring>
#include
<iostream> #include<algorithm> #define pi acos(-1) #define ll long long #define mod 10007 #define ls l,m,rt<<1 #define rs m+1,r,rt<<1|1 #pragma comment(linker, "/STACK:1024000000,1024000000") using namespace std; const double g=10.0,eps=1e-9; const int N=300+10,maxn=45000+10,inf=0x3f3f3f3f; double x[N],y[N]; ll G[N][N];
double d[N][N]; double dis(int a,int b) { return sqrt((x[a]-x[b])*(x[a]-x[b])+(y[a]-y[b])*(y[a]-y[b])); } bool line(int a,int b,int c) { ll x1=x[b]-x[a],y1=y[b]-y[a]; ll x2=x[c]-x[a],y2=y[c]-y[a]; if(x1*y2!=x2*y1)return 0; if(x1<0&&x2>0)return 0; return 1; } ll martix_tree(
int n) { ll ans=1; for(int i=1;i<n;i++) { for(int j=i+1;j<n;j++) { while(G[j][i]){ ll t=G[i][i]/G[j][i]; for(int k=i;k<n;k++) { G[i][k]=(G[i][k]-G[j][k]*t)%mod; swap(G[i][k],G[j][k]); } ans=-ans; } } if(G[i][i]==0)return 0; ans=(ans*G[i][i])%mod; } return (ans+mod)%mod; } int main() { ios::sync_with_stdio(false); cin.tie(0); int t,n,r; cin>>t; while(t--){ cin>>n>>r; for(int i=1;i<=n;i++) cin>>x[i]>>y[i]; for(int i=1;i<=n;i++) { d[i][i]=0; for(int j=i+1;j<=n;j++) d[i][j]=d[j][i]=dis(i,j); } for(int i=1;i<=n;i++) { for(int j=i+1;j<=n;j++) { if(d[i][j]>r) { d[i][j]=d[j][i]=0; continue; } for(int k=j+1;k<=n;k++) { if(line(i,j,k)) { if(d[i][j]>d[i][k])d[i][j]=d[j][i]=0; else d[i][k]=d[k][i]=0; } } } } memset(G,0,sizeof G); for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { if(d[i][j])G[i][j]=G[j][i]=-1,G[i][i]++; } } /* for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) cout<<G[i][j]<<" "; cout<<endl; }*/ ll ans=martix_tree(n); if(ans)cout<<ans<<endl; else cout<<-1<<endl; } return 0; }
martix_tree

hdu4305生成樹計數