zoukankan      html  css  js  c++  java
  • 天赋 HYSBZ

    小明有许多潜在的天赋,他希望学习这些天赋来变得更强。正如许多游戏中一样,小明也有n种潜在的天赋,但有
    一些天赋必须是要有前置天赋才能够学习得到的。也就是说,有一些天赋必须是要在学习了另一个天赋的条件下才
    能学习的。比如,要想学会"开炮",必须先学会"开枪"。一项天赋可能有多个前置天赋,但只需习得其中一个就可
    以学习这一项天赋。上帝不想为难小明,于是小明天生就已经习得了1号天赋-----"打架"。于是小明想知道学习完
    这n种天赋的方案数,答案对1,000,000,007取模。
     
    Input
    第一行一个整数n。
    接下来是一个n*n的01矩阵,第i行第j列为1表示习得天赋j的一个前置天赋为i。
    数据保证第一列和主对角线全为0。
    n<=300
    Output

    第一行一个整数,问题所求的方案数。

    Sample Input8 01111111 00101001 01010111 01001111 01110101 01110011 01111100 01110110

    Sample Output72373 Hint




    其实就是问你这个有向图的生成树个数。方法依旧是利用矩阵树定理,只不过与无向图不同的是,要将度数矩阵改成入度矩阵或出度矩阵,分别对应外向树和内向树。还有删掉的那行和那列必须是根的那行那列。

    A为邻接矩阵,D为度数矩阵,则基尔霍夫(Kirchhoff)

    矩阵即为:K=D−A。具体实现中,记 a 为Kirchhoff矩阵,则若存在 E(u,v),

    则 a[u][u]++ ,a[v][v]++,a[u][v]−−,a[v][u]−− 。即a[i][i]

     为 ii 点的度数, a[i][j] 为 i,ji,j之间边的条数的相反数。

    剩余系下没有除法,所以使用辗转相除高斯消元

    gauss之前要把数组内所有的数全变成mod意义下的正数




    #include <cstdio>
    #include <iostream>
    #include <cstring>
    using namespace std;
    typedef long long ll;
    const ll P=1000000007;
    int n;
    ll ans;
    char str[310];
    int d[310][310],lj[310][310];
    ll v[310][310];
    
    int main()
    {
        scanf("%d",&n);
        int i,j,k;
        for(i=0;i<n;i++)
        {
            scanf("%s",str);
            for(j=0;j<n;j++)
            {
                lj[i][j]=str[j]-'0';
                if(lj[i][j])    d[j][j]++;
            }
        }
        int ff=1;
        for(i=1;i<n;i++) for(j=1;j<n;j++) v[i][j]=(d[i][j]-lj[i][j]+P)%P;
        for(ans=1,i=1;i<n;i++)
        {
            for(j=i;j<n;j++) if(v[j][i]) break;
            if(j!=i) for(ff*=-1,k=i;k<n;k++)   swap(v[i][k],v[j][k]);
    
            for(j=i+1;j<n;j++)
            {
                //ll A=v[i][i],B=v[j][i],tmp,temp;
                while(v[j][i])
                {
                    ll t=v[i][i]/v[j][i];
                   // tmp=A/B,temp=A,A=B,B=temp%B;
                    for(ff*=-1,k=i;k<n;k++)
                        v[i][k]=(v[i][k]-t*v[j][k]%P+P)%P,
                        swap(v[i][k],v[j][k]);
                }
            }
            ans=ans*v[i][i]%P;
        }
        if(ff==-1 ) ans *=-1;
        ans %=P ;ans += P ;ans %= P;
        printf("%lld
    ",ans);
        return 0;
    }
  • 相关阅读:
    Python-爬虫-解析库(pyquery)的使用
    Python-爬虫-解析库(Beautiful Soup)的使用
    Python-爬虫-基本库(requests)使用-抓取猫眼电影Too100榜
    Python-爬虫-基本库(requests)使用
    Go基础及语法(五)
    Go基础及语法(四)
    Go基础及语法(三)
    Go基础及语法(二)
    Go基础及语法(一)
    MySQL8.0随笔整理
  • 原文地址:https://www.cnblogs.com/zhangbuang/p/10919720.html
Copyright © 2011-2022 走看看