1. 程式人生 > >1627 Join 生成樹計數模板題

1627 Join 生成樹計數模板題

                                                                                   URAL - 1627   Join

Businessman Petya recently bought a new house. This house has one floor with n × m square rooms, placed in rectangular lattice. Some rooms are pantries and the other ones are bedrooms. Now he wants to join all bedrooms with doors in such a way that there will be exactly one way between any pair of them. He can make doors only between neighbouring bedrooms (i.e. bedrooms having a common wall). Now he wants to count the number of different ways he can do it.

Input

First line contains two integers n and m (1 ≤ n, m ≤ 9)  — the number of lines and columns in the lattice. Next n lines contain exactly m characters representing house map, where "." means bedroom and "*" means pantry. It is guaranteed that there is at least one bedroom in the house.

Output

Output the number of ways to join bedrooms modulo 10 9.

Example

input output
2 2
..
..
4
2 2
*.
.*
0
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <map>

using namespace std;
const int maxn = 100 + 10;
const int maxm = 1010025;
const int INF = 0x3f3f3f3f;
const int mod = 1e9;
const double eps = 1e-8;
#define type long long

int n,m;

int d[maxn];
int g[maxn][maxn];
type c[maxn][maxn];

type det(type a[][maxn],int n)
{
  type ret=1;
  for(int i=1;i<=n;i++)
  {
    for(int j=i+1;j<=n;j++)
    {
      while(a[j][i])
      {
        type t=a[i][i]/a[j][i];
        for(int k=i;k<=n;k++)
            a[i][k]=(((a[i][k]-a[j][k]*t)%mod)+mod)%mod;

        for(int k=i;k<=n;k++)
            swap(a[i][k],a[j][k]);
        ret=-ret;
      }
    }
    if(a[i][i]==0)  return 0;
    ret=(((ret*a[i][i])%mod)+mod)%mod;
  }
  if(ret<0)   ret=-ret;
  return ret%mod;
}

type num_st(int n)
{
     for(int i = 1; i <= n; i++)
       for(int j = 1; j <= n; j++)
         {
           if(i == j) c[i][j] = d[i];
           else c[i][j] = -g[i][j];
         }
/*
    for(int i = 1; i <= n; i++)
     for(int j = 1; j <= n; j++)
        printf("%lld%c",c[i][j],j == n ? '\n' : ' ');
*/
    return det(c,n-1);
}

typedef pair<int,int> P;
map <P,int> mp;
int tot = 0;
string s[10];
int fx[4] = {0,0,1,-1};
int fy[4] = {1,-1,0,0};

bool check(int x, int y)
{
  if(x < 0 || y < 0 || x >= n || y >= m) return false;
  if(s[x][y] == '.') return true;
}
int main()
{
    scanf("%d%d",&n,&m);
    for(int i = 0; i < n; i++)
      {
         cin >> s[i];
         for(int j = 0; j < m; j++)
           if(s[i][j] == '.')  mp[P(i,j)] = ++tot;
      }
      memset(g,0,sizeof(g));
    for(int i = 0; i < n; i++)
          for(int j = 0; j < m; j++)
            {
               if(s[i][j] == '.')
               for(int k = 0; k < 4; k++)
                {
                  int di = i + fx[k];
                  int dj = j + fy[k];
                  if(check(di,dj))
                   {
                     int u = mp[P(i,j)];
                     int v = mp[P(di,dj)];
                     g[u][v] = g[v][u] = 1;
                   }
                }
            }
    for(int i = 1; i <= tot; i++)
       for(int j = 1; j <= tot; j++)
           if(i != j) d[i] += g[i][j];
    type ans = num_st(tot);
    printf("%lld\n",ans);
  return 0;
}