Total number of Spanning Trees in a Graph
Last Updated : 23 Jul, 2025
If a graph is a complete graph with n vertices, then total number of spanning trees is n(n-2) where n is the number of nodes in the graph. In complete graph, the task is equal to counting different labeled trees with n nodes for which have Cayley's formula.
What if Graph is not Complete?
Follow the below given procedure based on Kirchhoff's theorem
- STEP 1: Create Adjacency Matrix for the given graph.
- STEP 2: Replace all the diagonal elements with the degree of nodes. For eg. element at (1, 1) position of adjacency matrix will be replaced by the degree of node 1, element at (2, 2) position of adjacency matrix will be replaced by the degree of node 2, and so on.
- STEP 3: Replace all non-diagonal 1's with -1.
- STEP 4: Calculate co-factor for any element.
- STEP 5: The cofactor that you get is the total number of spanning tree for that graph.
Consider the following graph:
Adjacency Matrix for the above graph will be as follows:

After applying STEP 2 and STEP 3, adjacency matrix will look like
The co-factor for (1, 1) is 8. Hence total no. of spanning tree that can be formed is 8.
Note: Co-factor for all the elements will be same. Hence we can compute co-factor for any element of the matrix. This method is also known as Kirchhoff's Theorem. It can be applied to complete graphs also.
Let's see another example to solve these problems by making use of the Laplacian matrix.
A Laplacian matrix L, where
L[i, i] is the degree of node i and L[i, j] = -1 if there is an edge between nodes i and j,
and otherwise L[i, j] = 0.
Kirchhoff’s theorem provides a way to calculate the number of spanning trees for a given graph as a determinant of a special matrix.
Consider the following graph,
the undirected graphAll possible spanning trees are as follows
three spanning treesIn order to calculate the number of spanning trees, construct a Laplacian matrix L, where L[i, i] is the degree of node i and L[i, j] = 1 if there is an edge between nodes i and j, and otherwise L[i, j] = 0.
for the above graph, The Laplacian matrix will look like this
The number of spanning trees equals the determinant of a matrix.
The Determinant of a matrix that can be obtained when we remove any row and any column from L.
For example, if we remove the first row and column, the result will be,
The determinant is always the same, regardless of which row and column we remove from L.
Note: Cayley’s formula is a special case of Kirchhoff’s theorem because, in a complete graph of n nodes, the determinant is equal to nn-2
C++ // C++ program to count number of spanning // trees using matrix exponentiation #include <bits/stdc++.h> using namespace std; // Function to perform matrix multiplication: c = a * b void multiply(vector<vector<int>> &a, vector<vector<int>> &b, vector<vector<int>> &c, int v) { int mod = 1e9 + 7; vector<vector<int>> temp(v, vector<int>(v, 0)); // Triple nested loop for matrix // multiplication for (int i = 0; i < v; i++) { for (int j = 0; j < v; j++) { for (int k = 0; k < v; k++) { temp[i][j] = (temp[i][j] + 1LL * a[i][k] * b[k][j] % mod) % mod; } } } // Store the result back // into matrix c c = temp; } // Function to raise matrix a to power n and store in res void power(vector<vector<int>> &a, int n, vector<vector<int>> &res, int v) { int mod = 1e9 + 7; // Initialize res as identity matrix for (int i = 0; i < v; i++) { for (int j = 0; j < v; j++) { res[i][j] = (i == j); } } vector<vector<int>> temp(v, vector<int>(v, 0)); // Binary exponentiation while (n > 0) { if (n % 2 == 1) { multiply(a, res, temp, v); res = temp; } n /= 2; multiply(a, a, temp, v); a = temp; } } // Function to compute number of spanning trees // using adjacency matrix int numOfSpanningTree(vector<vector<int>> &graph, int v) { int mod = 1e9 + 7; vector<vector<int>> res(v, vector<int>(v, 0)); // Create a copy of the input // graph as matrix will be modified vector<vector<int>> temp = graph; // Raise matrix to (v - 2) power power(temp, v - 2, res, v); // Compute the sum of all values in // the resulting matrix int ans = 0; for (int i = 0; i < v; i++) { for (int j = 0; j < v; j++) { ans = (ans + res[i][j]) % mod; } } return ans; } // Driver code int main() { int v = 4; int e = 5; vector<vector<int>> graph = { {0, 1, 1, 1}, {1, 0, 1, 1}, {1, 1, 0, 1}, {1, 1, 1, 0} }; cout << numOfSpanningTree(graph, v); return 0; } Java // Java program to count number of spanning // trees using matrix exponentiation import java.util.*; class GfG { // Function to perform matrix multiplication: c = a * b static void multiply(int[][] a, int[][] b, int[][] c, int v) { int mod = (int)1e9 + 7; int[][] temp = new int[v][v]; // Triple nested loop for matrix // multiplication for (int i = 0; i < v; i++) { for (int j = 0; j < v; j++) { for (int k = 0; k < v; k++) { temp[i][j] = (int)((temp[i][j] + 1L * a[i][k] * b[k][j] % mod) % mod); } } } // Store the result back // into matrix c for (int i = 0; i < v; i++) { for (int j = 0; j < v; j++) { c[i][j] = temp[i][j]; } } } // Function to raise matrix a to power n and store in res static void power(int[][] a, int n, int[][] res, int v) { int mod = (int)1e9 + 7; // Initialize res as identity matrix for (int i = 0; i < v; i++) { for (int j = 0; j < v; j++) { res[i][j] = (i == j) ? 1 : 0; } } int[][] temp = new int[v][v]; // Binary exponentiation while (n > 0) { if (n % 2 == 1) { multiply(a, res, temp, v); for (int i = 0; i < v; i++) { for (int j = 0; j < v; j++) { res[i][j] = temp[i][j]; } } } n /= 2; multiply(a, a, temp, v); for (int i = 0; i < v; i++) { for (int j = 0; j < v; j++) { a[i][j] = temp[i][j]; } } } } // Function to compute number of spanning trees // using adjacency matrix static int numOfSpanningTree(int[][] graph, int v) { int mod = (int)1e9 + 7; int[][] res = new int[v][v]; // Create a copy of the input // graph as matrix will be modified int[][] temp = new int[v][v]; for (int i = 0; i < v; i++) { for (int j = 0; j < v; j++) { temp[i][j] = graph[i][j]; } } // Raise matrix to (v - 2) power power(temp, v - 2, res, v); // Compute the sum of all values in // the resulting matrix int ans = 0; for (int i = 0; i < v; i++) { for (int j = 0; j < v; j++) { ans = (ans + res[i][j]) % mod; } } return ans; } public static void main(String[] args) { int v = 4; int e = 5; int[][] graph = { {0, 1, 1, 1}, {1, 0, 1, 1}, {1, 1, 0, 1}, {1, 1, 1, 0} }; System.out.println(numOfSpanningTree(graph, v)); } } Python # Python program to count number of spanning # trees using matrix exponentiation # Function to perform matrix multiplication: c = a * b def multiply(a, b, c, v): mod = int(1e9) + 7 temp = [[0] * v for _ in range(v)] # Triple nested loop for matrix # multiplication for i in range(v): for j in range(v): for k in range(v): temp[i][j] = (temp[i][j] + a[i][k] * b[k][j] % mod) % mod # Store the result back # into matrix c for i in range(v): for j in range(v): c[i][j] = temp[i][j] # Function to raise matrix a to power n and store in res def power(a, n, res, v): mod = int(1e9) + 7 # Initialize res as identity matrix for i in range(v): for j in range(v): res[i][j] = 1 if i == j else 0 temp = [[0] * v for _ in range(v)] # Binary exponentiation while n > 0: if n % 2 == 1: multiply(a, res, temp, v) for i in range(v): for j in range(v): res[i][j] = temp[i][j] n //= 2 multiply(a, a, temp, v) for i in range(v): for j in range(v): a[i][j] = temp[i][j] # Function to compute number of spanning trees # using adjacency matrix def numOfSpanningTree(graph, v): mod = int(1e9) + 7 res = [[0] * v for _ in range(v)] # Create a copy of the input # graph as matrix will be modified temp = [row[:] for row in graph] # Raise matrix to (v - 2) power power(temp, v - 2, res, v) # Compute the sum of all values in # the resulting matrix ans = 0 for i in range(v): for j in range(v): ans = (ans + res[i][j]) % mod return ans # Driver code if __name__ == "__main__": v = 4 e = 5 graph = [ [0, 1, 1, 1], [1, 0, 1, 1], [1, 1, 0, 1], [1, 1, 1, 0] ] print(numOfSpanningTree(graph, v))
C# // C# program to count number of spanning // trees using matrix exponentiation using System; class GfG { // Function to perform matrix multiplication: c = a * b static void multiply(int[,] a, int[,] b, int[,] c, int v) { int mod = (int)1e9 + 7; int[,] temp = new int[v, v]; // Triple nested loop for matrix // multiplication for (int i = 0; i < v; i++) { for (int j = 0; j < v; j++) { for (int k = 0; k < v; k++) { temp[i, j] = (int)((temp[i, j] + 1L * a[i, k] * b[k, j] % mod) % mod); } } } // Store the result back // into matrix c for (int i = 0; i < v; i++) { for (int j = 0; j < v; j++) { c[i, j] = temp[i, j]; } } } // Function to raise matrix a to power n and store in res static void power(int[,] a, int n, int[,] res, int v) { // Initialize res as identity matrix for (int i = 0; i < v; i++) { for (int j = 0; j < v; j++) { res[i, j] = (i == j) ? 1 : 0; } } int[,] temp = new int[v, v]; // Binary exponentiation while (n > 0) { if (n % 2 == 1) { multiply(a, res, temp, v); for (int i = 0; i < v; i++) { for (int j = 0; j < v; j++) { res[i, j] = temp[i, j]; } } } n /= 2; multiply(a, a, temp, v); for (int i = 0; i < v; i++) { for (int j = 0; j < v; j++) { a[i, j] = temp[i, j]; } } } } // Function to compute number of spanning trees // using adjacency matrix static int numOfSpanningTree(int[,] graph, int v) { int mod = (int)1e9 + 7; int[,] res = new int[v, v]; // Create a copy of the input // graph as matrix will be modified int[,] temp = new int[v, v]; for (int i = 0; i < v; i++) { for (int j = 0; j < v; j++) { temp[i, j] = graph[i, j]; } } // Raise matrix to (v - 2) power power(temp, v - 2, res, v); // Compute the sum of all values in // the resulting matrix int ans = 0; for (int i = 0; i < v; i++) { for (int j = 0; j < v; j++) { ans = (ans + res[i, j]) % mod; } } return ans; } static void Main() { int v = 4; int[,] graph = { {0, 1, 1, 1}, {1, 0, 1, 1}, {1, 1, 0, 1}, {1, 1, 1, 0} }; Console.WriteLine(numOfSpanningTree(graph, v)); } } JavaScript // JavaScript program to count number of spanning // trees using matrix exponentiation // Function to perform matrix multiplication: c = a * b function multiply(a, b, c, v) { let mod = 1e9 + 7; let temp = Array.from({ length: v }, () => Array(v).fill(0) ); // Triple nested loop for matrix // multiplication for (let i = 0; i < v; i++) { for (let j = 0; j < v; j++) { for (let k = 0; k < v; k++) { temp[i][j] = (temp[i][j] + a[i][k] * b[k][j] % mod) % mod; } } } // Store the result back // into matrix c for (let i = 0; i < v; i++) { for (let j = 0; j < v; j++) { c[i][j] = temp[i][j]; } } } // Function to raise matrix a to power n and store in res function power(a, n, res, v) { let mod = 1e9 + 7; // Initialize res as identity matrix for (let i = 0; i < v; i++) { for (let j = 0; j < v; j++) { res[i][j] = (i === j) ? 1 : 0; } } let temp = Array.from({ length: v }, () => Array(v).fill(0) ); // Binary exponentiation while (n > 0) { if (n % 2 === 1) { multiply(a, res, temp, v); for (let i = 0; i < v; i++) { for (let j = 0; j < v; j++) { res[i][j] = temp[i][j]; } } } n = Math.floor(n / 2); multiply(a, a, temp, v); for (let i = 0; i < v; i++) { for (let j = 0; j < v; j++) { a[i][j] = temp[i][j]; } } } } // Function to compute number of spanning trees // using adjacency matrix function numOfSpanningTree(graph, v) { let mod = 1e9 + 7; let res = Array.from({ length: v }, () => Array(v).fill(0) ); // Create a copy of the input // graph as matrix will be modified let temp = graph.map(row => row.slice()); // Raise matrix to (v - 2) power power(temp, v - 2, res, v); // Compute the sum of all values in // the resulting matrix let ans = 0; for (let i = 0; i < v; i++) { for (let j = 0; j < v; j++) { ans = (ans + res[i][j]) % mod; } } return ans; } // Driver code let v = 4; let e = 5; let graph = [ [0, 1, 1, 1], [1, 0, 1, 1], [1, 1, 0, 1], [1, 1, 1, 0] ]; console.log(numOfSpanningTree(graph, v)); Time Complexity: O(v³*log(v)), due to repeated matrix multiplications for exponentiation. The program calculates the number of spanning trees in a graph using Matrix Tree Theorem, which involves computing the determinant of a matrix derived from the Laplacian matrix of the graph. In some approaches, this includes raising a matrix to the power of (v - 2), where v is the number of vertices.
Each matrix multiplication takes O(v³) time, and if matrix exponentiation is used efficiently (via exponentiation by squaring), the total number of multiplications is O(logn) where n = v - 2.
Space Complexity: O(v²), for storing the matrices and temporary result. The main space is used to store the adjacency matrix and any intermediate matrices during multiplication. Since each matrix is of size v × v.
Conclusion
This approach is generally feasible for small to medium-sized graphs, but may become inefficient for very large graphs due to the high time and space requirements.
Explore
DSA Fundamentals
Data Structures
Algorithms
Advanced
Interview Preparation
Practice Problem
My Profile