zoukankan      html  css  js  c++  java
  • 【BZOJ4894】天赋 有向图生成树计数

    【BZOJ4894】天赋

    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

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

    #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]++;
    		}
    	}
    	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(ans=P-ans,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(B)
    			{
    				tmp=A/B,temp=A,A=B,B=temp%B;
    				for(ans=P-ans,k=i;k<n;k++)	v[i][k]=(v[i][k]-tmp*v[j][k]%P+P)%P,swap(v[i][k],v[j][k]);
    			}
    		}
    		ans=ans*v[i][i]%P;
    	}
    	printf("%lld
    ",ans);
    	return 0;
    }
  • 相关阅读:
    NOI2018:屠龙勇士
    Hello world!
    bzoj5月月赛订正
    codeforces906 D
    bzoj2728 [HNOI2012]与非
    bzoj3884上帝与集合的正确用法
    bzoj2817[ZJOI2012]波浪
    2017多校联合赛1[题解]
    论如何优雅的用bitset来求四维偏序
    bzoj1488[HNOI2009]图的同构
  • 原文地址:https://www.cnblogs.com/CQzhangyu/p/7500479.html
Copyright © 2011-2022 走看看