1. 程式人生 > >P4111 [HEOI2015]小Z的房間

P4111 [HEOI2015]小Z的房間

== tin 操作 while lld def 鄰接 con print

你的房子可以看做是一個包含n*m個格子的格狀矩形,每個格子是一個房間或者是一個柱子。在一開始的時候,相鄰的格子之間都有墻隔著。
你想要打通一些相鄰房間的墻,使得所有房間能夠互相到達。在此過程中,你不能把房子給打穿,或者打通柱子(以及柱子旁邊的墻)。同時,你不希望在房子中有小偷的時候會很難抓,所以你希望任意兩個房間之間都只有一條通路。現在,你希望統計一共有多少種可行的方案。

矩陣樹求生成樹個數模板題
度數矩陣-鄰接矩陣=拉普拉斯矩陣
求拉普拉斯矩陣的任意一個代數余子數即可
#define int long long//記住這個騷操作!!!int->longlong範圍懶得手動改。但是記得int main要寫成signed main
#define mod 1000000000 int tot; int dx[4] = {0, 1, 0, -1}; int dy[4] = {1, 0, -1, 0}; int f[N][N]; char mp[N][N]; int n, m; int id[N][N]; int num = 0; int Gauss() { int ans = 1; for (int i = 1; i < tot; i++) { for (int j = i + 1; j < tot; j++) while (f[j][i]) {
int t = f[i][i] / f[j][i]; for (int k = i; k < tot; k++) f[i][k] = (f[i][k] - t * f[j][k] + mod) % mod; swap(f[i], f[j]); ans = -ans; } ans = (ans * f[i][i]) % mod; } return (ans + mod) % mod; } signed main() { sdf(n), sdf(m); for (int
i = 1; i <= n; i++) { char c; for (int j = 1; j <= m; j++) { cin >> mp[i][j]; if (mp[i][j] == .) id[i][j] = ++tot; } } For(x, 1, n) For(y, 1, m) For(k, 0, 3) { int tx = x + dx[k], ty = y + dy[k]; if (tx < 1 || ty < 1 || tx > n || ty > m || mp[x][y] == *) continue; if (mp[x][y] == mp[tx][ty]) { f[id[x][y]][id[x][y]]++; f[id[x][y]][id[tx][ty]] = -1; f[id[tx][ty]][id[x][y]] = -1; } } printf("%lld\n", Gauss()); return 0; }

P4111 [HEOI2015]小Z的房間