Ural 1627 Join(生成树计数)

http://acm.timus.ru/problem.aspx?space=1&num=1627

  生成树计数的题,直接用Matrix-Tree定理就可以解决问题了。

代码如下:

View Code
  1 #include <cstdio>
  2 #include <cstring>
  3 #include <algorithm>
  4 
  5 using namespace std;
  6 
  7 const int maxSize = 100;
  8 const int initMod = 1e9;
  9 typedef long long ll;
 10 int curSize = maxSize;
 11 
 12 struct Mat {
 13     ll val[maxSize][maxSize];
 14 
 15     Mat (ll one = 0) {
 16         for (int i = 0; i < curSize; i++) {
 17             for (int j = 0; j < curSize; j++) {
 18                 val[i][j] = 0;
 19             }
 20             val[i][i] = one;
 21         }
 22     }
 23 
 24     void print() {
 25         for (int i = 0; i < curSize; i++) {
 26             for (int j = 0; j < curSize; j++) {
 27                 printf("%lld ", val[i][j]);
 28             }
 29             puts("");
 30         }
 31         puts("~~~");
 32     }
 33 } mat;
 34 
 35 const int maxn = 12;
 36 char mp[maxn][maxn];
 37 
 38 void convert(int l, int r) {
 39     int mark = 0;
 40 
 41     for (int i = 0; i < l; i++) {
 42         for (int j = 0; j < r; j++) {
 43             mp[i][j] = (mp[i][j] == '.') ? ++mark : 0;
 44         }
 45     }
 46 //    printf("mark %d\n", mark);
 47 
 48     curSize = mark + 1;
 49     mat = Mat();
 50 
 51     for (int i = 0; i < l; i++) {
 52         for (int j = 0; j < r; j++) {
 53             if (!mp[i][j]) continue;
 54             if (i && mp[i - 1][j]) {
 55                 mat.val[mp[i][j]][mp[i - 1][j]]--;
 56                 mat.val[mp[i][j]][mp[i][j]]++;
 57             }
 58             if (j && mp[i][j - 1]) {
 59                 mat.val[mp[i][j]][mp[i][j - 1]]--;
 60                 mat.val[mp[i][j]][mp[i][j]]++;
 61             }
 62             if (i != l - 1 && mp[i + 1][j]) {
 63                 mat.val[mp[i][j]][mp[i + 1][j]]--;
 64                 mat.val[mp[i][j]][mp[i][j]]++;
 65             }
 66             if (j != r - 1 && mp[i][j + 1]) {
 67                 mat.val[mp[i][j]][mp[i][j + 1]]--;
 68                 mat.val[mp[i][j]][mp[i][j]]++;
 69             }
 70         }
 71     }
 72 //    puts("~~~");
 73 //    mat.print();
 74 }
 75 
 76 ll gcd(ll a, ll b) {
 77     return b ? gcd(b, a % b) : a;
 78 }
 79 
 80 ll lcm(ll a, ll b) {
 81     return a / gcd(a, b) * b;
 82 }
 83 
 84 ll cal() {
 85     ll ret = 1ll;
 86 
 87     curSize--;
 88     for (int p = 1, i, j; p < curSize; p++) {
 89         for (i = p + 1; i < curSize; i++) {
 90             while (mat.val[i][p]) {
 91                 int tmp = mat.val[p][p] / mat.val[i][p];
 92 
 93                 for (j = p; j < curSize; j++) {
 94                     mat.val[p][j] = ((mat.val[p][j] - mat.val[i][j] * tmp) % initMod + initMod) % initMod;
 95                     swap(mat.val[i][j], mat.val[p][j]);
 96                 }
 97                 ret = -ret;
 98             }
 99         }
100         ret *= mat.val[p][p];
101         ret = (ret % initMod + initMod) % initMod;
102 //        mat.print();
103     }
104 
105     return ret;
106 }
107 
108 int main() {
109 //    freopen("in", "r", stdin);
110 //    freopen("out", "w", stdout);
111     int n, m;
112 
113     while (~scanf("%d%d", &n, &m)) {
114         for (int i = 0; i < n; i++) {
115             scanf("%s", mp[i]);
116         }
117         convert(n, m);
118         printf("%lld\n", cal());
119     }
120 
121     return 0;
122 }

——written by Lyon

原文地址:https://www.cnblogs.com/LyonLys/p/Ural_1627_Lyon.html