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;
}
martix_tree

 

以上是关于hdu4305生成树计数的主要内容,如果未能解决你的问题,请参考以下文章

HDU4305:Lightning(生成树计数+判断点是否在线段上)

HDU 4305 Lightning Matrix Tree定理

[HDU 5304] 基环树计数

HDU1102 最小生成树prim算法

HDOJ4305 Lightning

hdu1875(最小生成树prime)