码迷,mamicode.com
首页 > 其他好文 > 详细

bzoj4894 天赋

时间:2017-12-31 21:00:16      阅读:157      评论:0      收藏:0      [点我收藏+]

标签:gis   long   input   online   gpo   get   nbsp   lin   output   

Description

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

Input

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

Output

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

Sample Input

8
01111111
00101001
01010111
01001111
01110101
01110011
01111100
01110110

Sample Output

72373
 
正解:矩阵树定理+高斯消元。
有向图树形图计数问题。。
假设边的方向是从根往叶子,那么需要消元的矩阵变成入度矩阵-邻接矩阵,同时必须去掉根的那一行和那一列再求行列式。
 
 1 #include <bits/stdc++.h>
 2 #define il inline
 3 #define RG register
 4 #define ll long long
 5 #define rhl (1000000007)
 6 
 7 using namespace std;
 8 
 9 int d[305][305],g[305][305],n,ans;
10 
11 il int gi(){
12   RG int x=0,q=1; RG char ch=getchar();
13   while ((ch<0 || ch>9) && ch!=-) ch=getchar();
14   if (ch==-) q=-1,ch=getchar();
15   while (ch>=0 && ch<=9) x=x*10+ch-48,ch=getchar();
16   return q*x;
17 }
18 
19 il char gc(){
20   RG char ch=getchar();
21   while (ch!=0 && ch!=1) ch=getchar();
22   return ch;
23 }
24 
25 il int qpow(RG int a,RG int b){
26   RG int ans=1;
27   while (b){
28     if (b&1) ans=1LL*ans*a%rhl;
29     a=1LL*a*a%rhl,b>>=1;
30   }
31   return ans;
32 }
33 
34 il void gauss(){
35   for (RG int i=2,id;i<=n;++i){
36     for (id=i;id<=n;++id) if (d[id][i]!=0) break;
37     for (RG int j=2;j<=n;++j) swap(d[i][j],d[id][j]);
38     RG int inv=qpow(d[i][i],rhl-2);
39     for (RG int j=i+1;j<=n;++j){
40       RG int tmp=d[j][i];
41       for (RG int k=i;k<=n;++k){
42     d[j][k]+=rhl-1LL*d[i][k]*inv%rhl*tmp%rhl;
43     if (d[j][k]>=rhl) d[j][k]-=rhl;
44       }
45     }
46     ans=1LL*ans*d[i][i]%rhl;
47   }
48   return;
49 }
50 
51 int main(){
52 #ifndef ONLINE_JUDGE
53   freopen("talent.in","r",stdin);
54   freopen("talent.out","w",stdout);
55 #endif
56   n=gi(),ans=1;
57   for (RG int i=1;i<=n;++i)
58     for (RG int j=1;j<=n;++j) g[i][j]=gc()==1;
59   for (RG int i=1,tmp=0;i<=n;++i,tmp=0){
60     for (RG int j=1;j<=n;++j) tmp+=g[j][i];
61     d[i][i]=tmp;
62   }
63   for (RG int i=1;i<=n;++i)
64     for (RG int j=1;j<=n;++j)
65       (d[i][j]+=rhl-g[i][j])%=rhl;
66   gauss(),cout<<ans; return 0;
67 }

 

bzoj4894 天赋

标签:gis   long   input   online   gpo   get   nbsp   lin   output   

原文地址:https://www.cnblogs.com/wfj2048/p/8143520.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!