2 条题解

  • 0
    @ 2025-10-8 17:09:53
    #include<bits/stdc++.h>
    using namespace std;
    const __int128 mod=1000000000;
    template<typename T>void qw(T x)
    {
        if(x<0)x=-x,putchar('-');
        if(x/10)qw(x/10);
        putchar(x%10+48); 
    }   
    __int128 a[110][110];//基尔霍夫矩阵
    void add(int x,int y){a[x][x]+=1;a[y][y]+=1;a[x][y]-=1;a[y][x]-=1;}
    /*
    任意图的生成树个数:
    生成树计数行列式a[i][i] = Di,Di为i的度数;
    a[i][j] = -k,k为i和j之间的边数。
    任去一行一列之后的行列式即为答案。
    (往往是去掉第n行第n列) 
    */
    int n,m;
    void gauss()
    {
    	__int128 ans=1;
    	int r=1;
        for(int c=1;c<=n;c++)
    	{
            for(int i=r+1;i<=n;i++)
    		{
                while(a[i][c])
    			{
                    __int128 bs=a[r][c]/a[i][c];
                    for(int j=1;j<=n;j++)a[r][j]=(a[r][j]-a[i][j]*bs)%mod;
                    swap(a[r],a[i]);
                    ans*=-1;
                    //每次交换两行,将答案取相反数
                }
            }
            if(a[r][c]!=0)r++;
    	}
        for(int i=1;i<=n;i++)ans=(ans*a[i][i]%mod+mod)%mod;
        qw(ans);
    }
    char s[15][15],id[15][15];
    int main()
    {
        scanf("%d%d", &n,&m);
        for(int i=1;i<=n;i++)scanf("%s",s[i]+1);
        int t=0;for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) if(s[i][j]=='.') id[i][j]=++t;//!将地图中的格子进行编号
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++){
                if(s[i][j]=='.'&&s[i+1][j]=='.') add(id[i][j],id[i+1][j]);
                if(s[i][j]=='.'&&s[i][j+1]=='.') add(id[i][j],id[i][j+1]);
                //只加向下的边和向右的边,防止重复
            }
        n=t-1;//去掉拉普拉斯矩阵的最后一行一列
        gauss();
        return 0;
    }
    
    • 0
      @ 2025-10-8 17:09:31
      #include<bits/stdc++.h>
      using namespace std;
      const __int128 mod=1000000000;
      template<typename T>void qw(T x)
      {
          if(x<0)x=-x,putchar('-');
          if(x/10)qw(x/10);
          putchar(x%10+48); 
      }   
      __int128 a[110][110];//基尔霍夫矩阵
      void add(int x,int y){a[x][x]+=1;a[y][y]+=1;a[x][y]-=1;a[y][x]-=1;}
      /*
      任意图的生成树个数:
      生成树计数行列式a[i][i] = Di,Di为i的度数;
      a[i][j] = -k,k为i和j之间的边数。
      任去一行一列之后的行列式即为答案。
      (往往是去掉第n行第n列) 
      */
      int n,m;
      void gauss()
      {
      	__int128 ans=1;
      	int r=1;
          for(int c=1;c<=n;c++)
      	{
              for(int i=r+1;i<=n;i++)
      		{
                  while(a[i][c])
      			{
                      __int128 bs=a[r][c]/a[i][c];
                      for(int j=1;j<=n;j++)a[r][j]=(a[r][j]-a[i][j]*bs)%mod;
                      swap(a[r],a[i]);
                      ans*=-1;
                      //每次交换两行,将答案取相反数
                  }
              }
              if(a[r][c]!=0)r++;
      	}
          for(int i=1;i<=n;i++)ans=(ans*a[i][i]%mod+mod)%mod;
          qw(ans);
      }
      char s[15][15],id[15][15];
      int main()
      {
          scanf("%d%d",&n,&m);
          for(int i=1;i<=n;i++)scanf("%s",s[i]+1);
          int t=0;for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) if(s[i][j]=='.') id[i][j]=++t;
          //将地图中的格子进行编号
          for(int i=1;i<=n;i++)
              for(int j=1;j<=m;j++)
      		{
                  if(s[i][j]=='.'&&s[i+1][j]=='.') add(id[i][j],id[i+1][j]);
                  if(s[i][j]=='.'&&s[i][j+1]=='.') add(id[i][j],id[i][j+1]);
                  //只加向下的边和向右的边,防止重复
              }
          n=t-1;//去掉拉普拉斯矩阵的最后一行一列
          gauss();
          return 0;
      }
      • 1

      信息

      ID
      5696
      时间
      1000ms
      内存
      256MiB
      难度
      9
      标签
      递交数
      13
      已通过
      4
      上传者