• hdu 4305 Lightning 生成树计数


    Matrix-Tree定理

    对于一个n个顶点的无向图G
    度矩阵D:设i顶点的度数为du[i],则D[i][i]=du[i]
    邻接矩阵A:若i和j之间有边,则A[i][j]=1,否则为0
    Kirchhoff矩阵C:C=D-A
    Matrix-Tree定理:对于一个无向图G,它的生成树个数等于其Kirchhoff矩阵任何一个n-1阶主子式的行列式的绝对值。

    例题

    题目链接:hdu 4305
    思路:先按要求建图,再求出Kirchhoff矩阵C,最后求C的任何一个n-1阶行列式的绝对值

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    const int N = 310;
    const int mod = 10007;
    LL x[N],y[N];
    LL dis[N][N];
    LL a[N][N];
    LL inv(LL a,LL b)
    {
        LL res=1;
        while(b)
        {
            if(b&1)res=(res*a)%mod;
            b>>=1;
            a=(a*a)%mod;
        }
        return res;
    }
    int judge(int i,int j,int k)//判断k是否是i和j连线上的点
    {
        LL x1=x[j]-x[i],y1=y[j]-y[i];
        LL x2=x[k]-x[i],y2=y[k]-y[i];
        if(x1*y2==x2*y1&&x1*x2>=0&&dis[i][j]>dis[i][k])return 1;
        return 0;
    }
    int main()
    {
        int T;
        cin>>T;
        while(T--)
        {
            memset(a,0,sizeof(a));
            memset(dis,0,sizeof(dis));
            int n;
            LL r;
            scanf("%d%lld",&n,&r);
            for(int i=1;i<=n;i++)
                scanf("%lld%lld",&x[i],&y[i]);
            for(int i=1;i<=n;i++)
                for(int j=i+1;j<=n;j++)
                    dis[i][j]=dis[j][i]=(x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]);
            for(int i=1;i<=n;i++)
            {
                for(int j=i+1;j<=n;j++)
                {
                    if(dis[i][j]>r*r)continue;
                    int k;
                    for(k=1;k<=n;k++)
                    {
                        if(k==i||k==j)continue;
                        if(judge(i,j,k))break;
                    }
                    if(k>n)
                    {
                        a[i][j]=a[j][i]=-1;
                        a[i][i]++;a[j][j]++;
                    }
                }
            }
            LL ans=1;
            //化成下三角形
            for(int i=1;i<n;i++)
            {
                LL t=inv(a[i][i],mod-2);
                for(int j=i+1;j<n;j++)
                {
                    LL tmp=a[j][i]*t%mod;
                    for(int k=1;k<n;k++)
                        a[j][k]=(a[j][k]-a[i][k]*tmp%mod+mod)%mod;
                }
            }
            for(int i=1;i<n;i++)
                ans=ans*a[i][i]%mod;
            if(ans==0)printf("-1
    ");
            else printf("%lld
    ",ans);
        }
        return 0;
    }
    
  • 相关阅读:
    mysql完全卸载教程(图文详细)
    windows:安装django
    01 Java的NIO三大组件以及buffer的原理以及应用
    16 JDK8的concurrenthashmap的原理介绍
    07 Java源码字节码层面简单分析
    06 Java字节码的基础知识
    05 Java的class文件的组成介绍
    04 G1垃圾回收器的介绍以及垃圾回收调优的基础知识和简单案例
    03 JVM中垃圾回收算法以及典型的垃圾回收器
    02 Java的引用类型以及应用场景
  • 原文地址:https://www.cnblogs.com/HooYing/p/11689473.html
Copyright © 2020-2023  润新知