• bzoj 4897 天赋 有向图的矩阵数定理


    4894: 天赋

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 104  Solved: 80
    [Submit][Status][Discuss]

    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

    HINT

    Source

    By 佚名上传

    题解:根向儿子,入度矩阵,儿子向根,出度矩阵。

    什么意思,第一种,比如u-->v则 v,v++ ,u,v--

    另外一直则 u-->v u,u++ v,u--

    第二种就是将边反向,然后变成第一种。

    有向树中删除的那一行必须是根的那一行。

     1 #pragma GCC optimize(2)
     2 #pragma G++ optimize(2)
     3 #include<iostream>
     4 #include<algorithm>
     5 #include<cmath>
     6 #include<cstdio>
     7 #include<cstring>
     8 
     9 #define ll long long
    10 #define N 307
    11 #define mod 1000000007
    12 using namespace std;
    13 inline int read()
    14 {
    15     int x=0,f=1;char ch=getchar();
    16     while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
    17     while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
    18     return x*f;
    19 }
    20 
    21 int n;
    22 ll a[N][N];
    23 char ch[N];
    24 ll ans=1;
    25 
    26 int main()
    27 {
    28     n=read();
    29     for (int i=1;i<=n;i++)
    30     {
    31         scanf("%s",ch+1);
    32         for (int j=1;j<=n;j++)
    33             if(ch[j]=='1') a[j][j]++,a[i][j]--;
    34     }
    35     for (int i=2;i<=n;i++)
    36     {
    37         for (int j=i+1;j<=n;j++)
    38         {
    39             int A=a[i][i],B=a[j][i];
    40             while(B)
    41             {
    42                 int t=A/B;A%=B;swap(A,B);
    43                 for(int k=i;k<=n;k++)(a[i][k]=a[i][k]-t*a[j][k]%mod+mod)%=mod;
    44                 for(int k=i;k<=n;k++)swap(a[i][k],a[j][k]);
    45                 ans=-ans;
    46             }
    47         }
    48         if(!a[i][i])cout<<i<<endl;
    49         (ans*=a[i][i])%=mod;
    50         if(!a[i][i])break;
    51     }
    52     printf("%lld
    ",(ans%mod+mod)%mod);
    53 }
  • 相关阅读:
    软件定义网络实验4:Open vSwitch 实验——Mininet 中使用 OVS 命令(实验过程及结果记录)
    软件定义网络实验3:测量路径的损耗率 (实验过程及结果记录)
    第一次个人编程作业
    软件定义网络实验2:Mininet拓扑的命令脚本生成(实验过程及结果记录)
    软件定义网络实验1:Mininet源码安装和可视化拓扑工具(实验过程及结果记录)
    第一次博客作业
    第07组(69) 需求分析报告
    第七组(69)团队展示
    第三次作业
    结对编程作业
  • 原文地址:https://www.cnblogs.com/fengzhiyuan/p/8487449.html
Copyright © 2020-2023  润新知