hdu4305生成树计数
Posted walfy
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hdu4305生成树计数相关的知识,希望对你有一定的参考价值。
先预处理出距离,然后判断是否可行,要注意判断是否在一条直线上时判断是在两侧还是一边(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; }
以上是关于hdu4305生成树计数的主要内容,如果未能解决你的问题,请参考以下文章
HDU4305:Lightning(生成树计数+判断点是否在线段上)