The number of spanning trees is a determinant. For an undirected multigraph with Laplacian ( = number of – edges, loops ignored), every cofactor (delete row and column ) equals the number of spanning trees. With edge weights in it is . For directed graphs (Tutte), arborescences into root are counted by deleting row/column of , and arborescences out of by . Determinants are in Determinants.
ll detMod(vector<vector<ll>> a, ll p) { // O(n^3), p prime, entries in [0, p)
int n = sz(a); ll det = 1;
for (int c = 0; c < n; c++) {
int piv = -1; for (int r = c; r < n; r++) if (a[r][c]) { piv = r; break; }
if (piv < 0) return 0;
if (piv != c) swap(a[piv], a[c]), det = (p - det) % p;
det = det * a[c][c] % p;
ll inv = 1; for (ll b = a[c][c], e = p - 2; e; e >>= 1, b = b * b % p) if (e & 1) inv = inv * b % p;
for (int r = c + 1; r < n; r++) if (a[r][c]) {
ll f = a[r][c] * inv % p;
for (int k = c; k < n; k++) a[r][k] = (a[r][k] - f * a[c][k] % p + p) % p;
}
}
return det;
}
ll countSpanningTrees(int n, const vector<array<ll, 3>>& E, ll p) { // {u, v, weight}; undirected
if (n == 1) return 1;
vector<vector<ll>> L(n, vector<ll>(n));
auto add = [&](int i, int j, ll x) { L[i][j] = ((L[i][j] + x) % p + p) % p; };
for (auto [u, v, w] : E) if (u != v) add(u, u, w), add(v, v, w), add(u, v, -w), add(v, u, -w);
vector<vector<ll>> M(n - 1, vector<ll>(n - 1));
for (int i = 1; i < n; i++) for (int j = 1; j < n; j++) M[i - 1][j - 1] = L[i][j];
return detMod(M, p);
}
ll countArborescences(int n, int r, const vector<array<ll, 3>>& E, ll p, bool outTree) { // directed u -> v
vector<vector<ll>> L(n, vector<ll>(n));
for (auto [u, v, w] : E) if (u != v) {
int d = outTree ? v : u; // out-trees: in-degree on the diagonal
L[d][d] = (L[d][d] + w) % p; L[u][v] = ((L[u][v] - w) % p + p) % p;
}
vector<vector<ll>> M; for (int i = 0; i < n; i++) if (i != r) { M.push_back({}); for (int j = 0; j < n; j++) if (j != r) M.back().push_back(L[i][j]); }
return n == 1 ? 1 : detMod(M, p);
}Over the integers (exact, no modulus) use fraction-free Bareiss elimination; the count can be huge, so contest problems ask modulo a prime.
Proof: Cauchy–Binet
Orient each edge arbitrarily and let be the incidence matrix ( at the head, at the tail, weighted version: scale column by ). Then and deleting row of gives with . Cauchy–Binet: over -subsets of edges. If contains a cycle, the columns of the cycle (signed around it) sum to zero, so . If is a spanning tree, some vertex is a leaf of ; its row has a single , and expanding along it reduces to the tree with that leaf removed, so by induction (weighted: ). Hence the cofactor is . If has edges and no cycle it is a spanning tree, so these are all cases.
Directed: for in-trees into , write and expand the reduced determinant by choosing one out-edge per non-root vertex (each row is “out-degree minus out-neighbours”); choices containing a cycle cancel in pairs by a sign-reversing involution on the cycles, leaving exactly the choices that form an in-tree, each with sign . Out-trees are the transpose.
Consequences
| Graph | Spanning trees |
|---|---|
| (Cayley) | |
| cycle | |
| wheel ( rim vertices) | (Lucas numbers) |
| hypercube | |
| with a forest of trees of sizes forced in |
- Count MSTs: process weight classes in increasing order; for class , contract all lighter edges (DSU), and in each connected component of the class’s edges on the contracted vertices count spanning trees; multiply over all classes and components.
- Sum over spanning trees of the total edge weight: where is the unweighted reduced Laplacian () and the reduced Laplacian with weights ; equivalently compute the determinant over .
- Probability that edge is in a uniform random spanning tree = (effective resistance), and . Effective resistance itself is also a determinant ratio: for any single-deleted cofactor.
- Eulerian circuits (BEST theorem): for a connected Eulerian digraph, where is the number of arborescences into any fixed vertex (Euler Tours).
- Random spanning trees: Wilson’s algorithm (loop-erased random walks) samples uniformly without determinants; Aldous–Broder (first-entrance edges of a random walk) too.
Proof: Cayley and the MST count
Cayley: the reduced Laplacian of is of size ( all ones), with eigenvalues (multiplicity ) and , so . Counting MSTs: Kruskal’s runs on all tie-breaking orders produce exactly the MSTs; before class the DSU components are fixed, and within the class any spanning forest of the class edges over the contracted components can be chosen independently per component of that multigraph. So the number of MSTs is the product over classes and components of the number of spanning trees of the contracted multigraph, each given by the matrix-tree theorem.