• BZOJ4031: [HEOI2015]小Z的房间


    n,m<=9,n*m的网格图,相邻的.可连边,问把所有的.连成一棵树有多少方案,%1e9。

    直接矩阵树,然而高斯消元时模数不是质数没法直接除,所以利用行列式的性质,某一行乘某个数加到另一行上,这样辗转相除。

     1 #include<stdio.h>
     2 #include<string.h>
     3 #include<algorithm>
     4 #include<stdlib.h>
     5 //#include<queue>
     6 #include<math.h>
     7 //#include<time.h>
     8 //#include<iostream>
     9 using namespace std;
    10 
    11 int n,m,tot=0;
    12 char mp[13][13];
    13 int mat[111][111],who[111][111];
    14 const int mod=1e9;
    15 
    16 int gauss(int n)
    17 {
    18     for (int i=1;i<=n;i++)
    19         for (int j=1;j<=n;j++)
    20             mat[i][j]+=mat[i][j]<0?mod:0;
    21     int ans=1;
    22     for (int i=1;i<=n;i++)
    23         for (int j=i+1;j<=n;j++)
    24         {
    25             int A=mat[i][i],B=mat[j][i];
    26             while (B)
    27             {
    28                 int t=A/B; A%=B; swap(A,B);
    29                 for (int k=i;k<=n;k++)
    30                     mat[i][k]-=1ll*mat[j][k]*t%mod,
    31                     mat[i][k]+=mat[i][k]<0?mod:0;
    32                 for (int k=i;k<=n;k++) {int t=mat[j][k]; mat[j][k]=mat[i][k]; mat[i][k]=t;}
    33                 ans=ans==1?mod-1:1;
    34             }
    35         }
    36     for (int i=1;i<=n;i++) ans=1ll*ans*mat[i][i]%mod;
    37     return ans;
    38 }
    39 
    40 int main()
    41 {
    42     scanf("%d%d",&n,&m);
    43     for (int i=1;i<=n;i++) scanf("%s",mp[i]+1);
    44     for (int i=1;i<=n;i++)
    45         for (int j=1;j<=m;j++)
    46             if (mp[i][j]=='.') who[i][j]=++tot;
    47     for (int i=1;i<=n;i++)
    48         for (int j=1;j<=m;j++)
    49             if (mp[i][j]=='.')
    50             {
    51                 if (mp[i+1][j]=='.') mat[who[i][j]][who[i+1][j]]--,mat[who[i][j]][who[i][j]]++;
    52                 if (mp[i][j+1]=='.') mat[who[i][j]][who[i][j+1]]--,mat[who[i][j]][who[i][j]]++;
    53                 if (mp[i-1][j]=='.') mat[who[i][j]][who[i-1][j]]--,mat[who[i][j]][who[i][j]]++;
    54                 if (mp[i][j-1]=='.') mat[who[i][j]][who[i][j-1]]--,mat[who[i][j]][who[i][j]]++;
    55             }
    56     printf("%d
    ",gauss(tot-1));
    57     return 0;
    58 }
    View Code
  • 相关阅读:
    寒假 学习进度七
    寒假学习进度
    寒假学习进度五
    寒假学习进度四
    寒假学习进度三
    寒假学习进度二
    Spark实验五
    半篇论文笔记
    REPL
    Scala基本语法及操作、程序控制结构
  • 原文地址:https://www.cnblogs.com/Blue233333/p/8133866.html
Copyright © 2020-2023  润新知