zoukankan      html  css  js  c++  java
  • 【bzoj4894】天赋 矩阵树定理

    题目描述

    小明有许多潜在的天赋,他希望学习这些天赋来变得更强。正如许多游戏中一样,小明也有n种潜在的天赋,但有一些天赋必须是要有前置天赋才能够学习得到的。也就是说,有一些天赋必须是要在学习了另一个天赋的条件下才能学习的。比如,要想学会"开炮",必须先学会"开枪"。一项天赋可能有多个前置天赋,但只需习得其中一个就可以学习这一项天赋。上帝不想为难小明,于是小明天生就已经习得了1号天赋-----"打架"。于是小明想知道学习完这n种天赋的方案数,答案对1,000,000,007取模。(两种方案不同指的是存在某种天赋的前置天赋不同)

    输入

    第一行一个整数n。
    接下来是一个n*n的01矩阵,第i行第j列为1表示习得天赋j的一个前置天赋为i。
    数据保证第一列和主对角线全为0。
    n<=300

    输出

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

    样例输入

    8
    01111111
    00101001
    01010111
    01001111
    01110101
    01110011
    01111100
    01110110

    样例输出

    72373


    题解

    矩阵树定理

    读明白题以后发现求的就是外向树形图的个数,于是使用矩阵树定理解决。

    与求生成树个数不同的是,外向树形图用的矩阵是 入度矩阵-邻接矩阵 ,并且删去的一行一列不能随便选择,必须是根所在的那一行那一列。

    然后高斯消元求一下行列式的值即可。

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #define N 310
    #define mod 1000000007
    using namespace std;
    typedef long long ll;
    ll a[N][N];
    char str[N];
    inline ll pow(ll x , ll y)
    {
    	ll ans = 1;
    	while(y)
    	{
    		if(y & 1) ans = ans * x % mod;
    		x = x * x % mod , y >>= 1;
    	}
    	return ans;
    }
    int main()
    {
    	int n , i , j , k , d = 0;
    	ll t , ans = 1;
    	scanf("%d" , &n);
    	for(i = 0 ; i < n ; i ++ )
    	{
    		scanf("%s" , str);
    		for(j = 0 ; j < n ; j ++ )
    			if(str[j] == '1')
    				a[j][j] ++ , a[i][j] -- ;
    	}
    	for(i = 1 ; i < n ; i ++ )
    	{
    		for(j = i ; j < n ; j ++ )
    			if(a[j][i])
    				break;
    		if(j >= n) continue;
    		if(j != i)
    			for(d ^= 1 , k = i ; k < n ; k ++ )
    				swap(a[i][k] , a[j][k]);
    		ans = ans * a[i][i] % mod;
    		for(t = pow(a[i][i] , mod - 2) , j = i ; j < n ; j ++ ) a[i][j] = a[i][j] * t % mod;
    		for(j = i + 1 ; j < n ; j ++ )
    			for(t = a[j][i] , k = i ; k < n ; k ++ )
    				a[j][k] = (a[j][k] - a[i][k] * t % mod + mod) % mod;
    	}
    	for(i = 1 ; i < n ; i ++ ) ans = ans * a[i][i] % mod;
    	if(d) ans = (mod - ans) % mod;
    	printf("%lld
    " , ans);
    	return 0;
    }
    

     

  • 相关阅读:
    flash 语法 入门
    flash 代码 雪花飘落
    test windows live writer
    网站索引
    [转]jquery入门简介
    forcast iframe 及 四款播放器
    flash
    flash 备忘
    浏览器默认HTML的CSS样式属性
    简单多线程拷贝单文件示例
  • 原文地址:https://www.cnblogs.com/GXZlegend/p/7493203.html
Copyright © 2011-2022 走看看