矩陣樹定理與BEST定理

Lu_xZ發表於2024-09-26

行列式

定義:\(\det(A)\),又記作 \(\vert A\vert\),等於 \(\sum_p (-1)^{\tau(p)} \prod_{i = 1}^nA_{i, p_i}\),其中 \(p\)\(1 \sim n\) 的排列,\(\tau(p)\) 表示排列 \(p\) 的逆序對數。

1. 對於一個上三角矩陣,他的行列式等於主對角線所有值的乘積。

要使 \(A_{n, p_n} \ne 0\)\(p_n\) 只能取 \(n\);要使 \(A_{n - 1, p_{n - 1}} \ne 0\)\(p_{n - 1} \in \{n - 1, n\}\),但是 \(n\) 已經被用過了,\(p_{n - 1} = n - 1\)

以此類推,使 \(\prod A_{i, p_i}\) 非零的只有唯一一個排列 \(p_i = i\),此時 \(\tau(p) = 0\)

2. 單位矩陣的行列式為 \(1\),即 \(\vert I\vert = 1\)

根據 \(I_{i, j} = [i = j]\) 以及 定理1 易證。

3. 交換矩陣兩行,行列式變號。

交換 \(i, j\) 等價於交換每個排列的 \(p_i, p_j\),這會使所有 \(\tau(p)\) 奇偶性改變,相當於整體乘了個 \(-1\)

4. 將矩陣某行乘上一個常數,行列式乘上相同常數。

不妨將第 \(r\) 行所有元素乘 \(k\)\(\prod_{i = 1}^n A_{i, p_i}\) 恰好包含一個第 \(r\) 行元素,把 \(k\) 提出來。

5. 若矩陣有相同的兩行,則行列式為 \(0\)

交換兩行會使行列式變號,但是矩陣沒變,即 \(\vert A\vert = -\vert A\vert \implies \vert A\vert = 0\)

6. 若矩陣有兩行存在倍數關係,則行列式為 \(0\)

\(k \vert A\vert = -k\vert A\vert \implies \vert A\vert = 0\)

7. 若兩個矩陣至多有一行不等,將這不等的一行相加得到的新矩陣的行列式等於原行列式之和。

設不等的行編號為 \(c\),新矩陣 \(S\) 滿足 \(S_i = A_i = B_i,\ S_c = A_c + B_c(i \ne c)\)

\(\prod_{i = 1}^nS_{i, p_i} = (A_{c, p_c} + B_{c, p_c})\prod_{i = 1}^n[i\ne c]A_{i, p_i} = \prod_{i = 1}^nA_{i, p_i} + \prod_{i = 1}^nB_{i, p_i}\)

8. 將矩陣的某行加上另一行的倍數,行列式不變。

設把 \(c\)\(k\) 倍加到 \(d\) 上,設新矩陣為 \(C\)

\(B_i = A_i, B_d = kA_c(i \ne c)\),根據定理 7可得 \(\vert A\vert + \vert B\vert = \vert C\vert\),根據定理6可得 \(\vert B\vert = 0\)

高斯消元

步驟略。

P4783 【模板】矩陣求逆

題意:求一個 \(n \times n\) 的矩陣 \(A\) 在模 \(10^9 + 7\) 意義下的逆矩陣。

\(A\) 進行線性變換相當於左乘一個矩陣,也就是說把 \(A\) 變換(消元)到單位矩陣 \(I\),相當於左乘 \(A^{-1}\)

有恆等式 \(A^{-1} \times A = I\),那麼在 \(A\) 變換到 \(I\) 的同時 \(I\) 也做同樣的變換,最後得到 \(A^{-1} \times I = A^{-1}\)

矩陣可逆當且僅當 \(\vert A\vert \ne 0\),即滿秩。submission

P7112 【模板】行列式求值

題意:給定一個 \(n\) 階行列式,求 \(\vert A\vert\)。結果對 \(p\) 取模,不保證 \(p\) 是素數。

\(A\) 消成上三角矩陣,最後答案就是主對角線之積。

加上某一行的倍數不改變答案,而交換兩行會使符號改變,因此記錄交換了多少次。

沒有必要對一行乘某個常數的操作,否則還有額外記錄乘了多少東西。

\(p\) 沒有特殊性質,不能求逆元,因此採用類似「輾轉相除法」對兩行消元,時間複雜度 \(O(n^3\log p)\)

#include<bits/stdc++.h>
#define eb emplace_back
#define ep emplace
using namespace std;

using ll = long long;

int n, p, sgn; ll a[605][605];

int main() {
	cin.tie(0)->sync_with_stdio(0);
	cin >> n >> p;
	for(int i = 1; i <= n; ++ i) {
		for(int j = 1; j <= n; ++ j) {
			cin >> a[i][j];
			a[i][j] %= p;
		}
	}
	for(int k = 1; k <= n; ++ k) {
		for(int i = k; i <= n; ++ i) {
			if(a[i][k]) {
				if(i != k) {
					swap(a[i], a[k]), sgn ^= 1;
				}
				break;
			}
		}
		if(!a[k][k]) return cout << 0, 0;
		for(int i = k + 1; i <= n; ++ i) {
			while(a[i][k]) {
				if(a[i][k] < a[k][k]) {
					swap(a[i], a[k]), sgn ^= 1;
				} 
				ll q = a[i][k] / a[k][k];
				for(int j = k; j <= n; ++ j) {
					a[i][j] = (a[i][j] + p - q * a[k][j] % p) % p;
				}
			}
		}
	}
	ll tmp = 1;
	for(int i = 1; i <= n; ++ i) tmp = tmp * a[i][i] % p;
	cout << (sgn ? (p - tmp) % p : tmp);
	return 0;
}

矩陣樹定理

無向圖生成樹個數

\(D\) 為無向圖的度數矩陣,

有向圖生成樹個數

相關文章