Number of Spanning Trees in a Graph (original) (raw)

Last Updated : 9 May, 2026

Given a connected **undirected graph with **v vertices and its **adjacency matrix representation, determine the total number of spanning trees that can be formed from the graph.

A **spanning tree is a subgraph that connects all vertices of a graph with exactly v-1 edges and contains no cycles.

**Example:

**Input: v = 4 adj[][] = [ [0,1,0,0], [1,0,1,0], [0,1,0,1], [0,0,1,0] ]

frame_3205

**Output: 1
**Explanation: The graph is connected and has exactly v-1 edges, so it is already a tree, hence only one spanning tree exists.

**Input: v = 4 adj[][] = [ [0,1,1,0], [1,0,1,0], [1,1,0,1], [0,0,1,0] ]

frame_3204

**Output: 3
**Explanation: The graph has one cycle among nodes 0, 1, and 2, so removing one edge forms a spanning tree. Since the cycle has 3 edges, removing any one gives 3 possible spanning trees.

frame_3203-

Try It Yourselfredirect icon

Using Kirchhoff's Theorem

Kirchhoff’s Theorem works by converting the graph into a matrix form that captures how nodes are connected. This matrix (called the Laplacian matrix) represents the structure of the graph, and its determinant (cofactor) gives the total number of spanning trees.

Consider the following graph,

frame_3202

All possible spanning trees are as follows,

frame_3206

Here are the steps showing how the approach works to find the number of spanning trees in the given graph using Kirchhoff’s Theorem.

matrix_8

A Laplacian matrix L, where

**Cayley’s formula for Complete Graph : Itis a special case of Kirchhoff’s theorem because, in a complete graph of n nodes, the determinant is equal to n^(n-2).

Screenshot_20230311_014727

It works here because the Laplacian matrix represents how all nodes in the graph are connected. The determinant expands into all possible edge combinations, and due to its mathematical properties, invalid ones (cycles or disconnected) cancel out. As a result, only valid spanning trees remain, so the determinant directly gives their total count.

C++ `

#include #include #include #include using namespace std;

// Determinant using Gaussian elimination double determinant(vector<vector> mat, int n) { double det = 1.0;

for (int i = 0; i < n; i++) {

    // Find pivot
    int pivot = i;
    for (int j = i + 1; j < n; j++) {
        if (fabs(mat[j][i]) > fabs(mat[pivot][i]))
            pivot = j;
    }

    // If pivot is zero → determinant = 0
    if (fabs(mat[pivot][i]) < 1e-9)
        return 0;

    // Swap rows
    if (i != pivot) {
        swap(mat[i], mat[pivot]);
        det *= -1;
    }

    det *= mat[i][i];

    // Eliminate below
    for (int j = i + 1; j < n; j++) {
        double factor = mat[j][i] / mat[i][i];
        for (int k = i; k < n; k++) {
            mat[j][k] -= factor * mat[i][k];
        }
    }
}

return det;

}

// Number of spanning trees int numOfSpanningTree(vector<vector> &graph, int n) {

// Laplacian matrix
vector<vector<double>> L(n, vector<double>(n, 0));

for (int i = 0; i < n; i++) {
    int degree = 0;

    for (int j = 0; j < n; j++) {
        if (graph[i][j]) {
            degree++;
            if (i != j) L[i][j] = -1;
        }
    }

    L[i][i] = degree;
}

// Minor matrix
vector<vector<double>> minor(n - 1, vector<double>(n - 1));

for (int i = 0; i < n - 1; i++) {
    for (int j = 0; j < n - 1; j++) {
        minor[i][j] = L[i][j];
    }
}

// Determinant
return (int)round(determinant(minor, n - 1));

}

int main() { int v = 4;

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

import java.util.*;

class GfG {

// Determinant using Gaussian elimination
static double determinant(double[][] mat, int n) {
    double det = 1.0;

    for (int i = 0; i < n; i++) {

        // Find pivot
        int pivot = i;
        for (int j = i + 1; j < n; j++) {
            if (Math.abs(mat[j][i]) > Math.abs(mat[pivot][i]))
                pivot = j;
        }

        // If pivot is zero → determinant = 0
        if (Math.abs(mat[pivot][i]) < 1e-9)
            return 0;

        // Swap rows
        if (i != pivot) {
            double[] tempRow = mat[i];
            mat[i] = mat[pivot];
            mat[pivot] = tempRow;
            det *= -1;
        }

        det *= mat[i][i];

        // Eliminate below
        for (int j = i + 1; j < n; j++) {
            double factor = mat[j][i] / mat[i][i];
            for (int k = i; k < n; k++) {
                mat[j][k] -= factor * mat[i][k];
            }
        }
    }

    return det;
}

// Function to compute number of spanning trees 
// using adjacency matrix
static int numOfSpanningTree(int[][] graph, int v) {

    // Laplacian matrix
    double[][] L = new double[v][v];

    for (int i = 0; i < v; i++) {
        int degree = 0;

        for (int j = 0; j < v; j++) {
            if (graph[i][j] == 1) {
                degree++;
                if (i != j) L[i][j] = -1;
            }
        }

        L[i][i] = degree;
    }

    // Minor matrix
    double[][] minor = new double[v - 1][v - 1];

    for (int i = 0; i < v - 1; i++) {
        for (int j = 0; j < v - 1; j++) {
            minor[i][j] = L[i][j];
        }
    }

    // Determinant
    return (int)Math.round(determinant(minor, v - 1));
}

public static void main(String[] args) {
    int v = 4;

    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

Determinant using Gaussian elimination

def determinant(mat, n): det = 1.0

for i in range(n):

    # Find pivot
    pivot = i
    for j in range(i + 1, n):
        if abs(mat[j][i]) > abs(mat[pivot][i]):
            pivot = j

    # If pivot is zero → determinant = 0
    if abs(mat[pivot][i]) < 1e-9:
        return 0

    # Swap rows
    if i != pivot:
        mat[i], mat[pivot] = mat[pivot], mat[i]
        det *= -1

    det *= mat[i][i]

    # Eliminate below
    for j in range(i + 1, n):
        factor = mat[j][i] / mat[i][i]
        for k in range(i, n):
            mat[j][k] -= factor * mat[i][k]

return det

Function to compute number of spanning trees

using adjacency matrix

def numOfSpanningTree(graph, v):

# Laplacian matrix
L = [[0.0] * v for _ in range(v)]

for i in range(v):
    degree = 0

    for j in range(v):
        if graph[i][j] == 1:
            degree += 1
            if i != j:
                L[i][j] = -1

    L[i][i] = degree

# Minor matrix
minor = [[0.0] * (v - 1) for _ in range(v - 1)]

for i in range(v - 1):
    for j in range(v - 1):
        minor[i][j] = L[i][j]

# Determinant
return round(determinant(minor, v - 1))

if name == "main": v = 4

graph = [
    [0, 1, 1, 1],
    [1, 0, 1, 1],
    [1, 1, 0, 1],
    [1, 1, 1, 0]
]

print(numOfSpanningTree(graph, v))  # Output: 16

C#

using System;

class GfG {

// Determinant using Gaussian elimination
static double determinant(double[,] mat, int n) {
    double det = 1.0;

    for (int i = 0; i < n; i++) {

        // Find pivot
        int pivot = i;
        for (int j = i + 1; j < n; j++) {
            if (Math.Abs(mat[j, i]) > Math.Abs(mat[pivot, i]))
                pivot = j;
        }

        // If pivot is zero → determinant = 0
        if (Math.Abs(mat[pivot, i]) < 1e-9)
            return 0;

        // Swap rows
        if (i != pivot) {
            for (int k = 0; k < n; k++) {
                double temp = mat[i, k];
                mat[i, k] = mat[pivot, k];
                mat[pivot, k] = temp;
            }
            det *= -1;
        }

        det *= mat[i, i];

        // Eliminate below
        for (int j = i + 1; j < n; j++) {
            double factor = mat[j, i] / mat[i, i];
            for (int k = i; k < n; k++) {
                mat[j, k] -= factor * mat[i, k];
            }
        }
    }

    return det;
}

// Function to compute number of spanning trees 
// using adjacency matrix
static int numOfSpanningTree(int[,] graph, int v) {

    // Laplacian matrix
    double[,] L = new double[v, v];

    for (int i = 0; i < v; i++) {
        int degree = 0;

        for (int j = 0; j < v; j++) {
            if (graph[i, j] == 1) {
                degree++;
                if (i != j) L[i, j] = -1;
            }
        }

        L[i, i] = degree;
    }

    // Minor matrix
    double[,] minor = new double[v - 1, v - 1];

    for (int i = 0; i < v - 1; i++) {
        for (int j = 0; j < v - 1; j++) {
            minor[i, j] = L[i, j];
        }
    }

    // Determinant
    return (int)Math.Round(determinant(minor, v - 1));
}

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

// Determinant using Gaussian elimination function determinant(mat, n) { let det = 1.0;

for (let i = 0; i < n; i++) {

    // Find pivot
    let pivot = i;
    for (let j = i + 1; j < n; j++) {
        if (Math.abs(mat[j][i]) > Math.abs(mat[pivot][i]))
            pivot = j;
    }

    // If pivot is zero → determinant = 0
    if (Math.abs(mat[pivot][i]) < 1e-9)
        return 0;

    // Swap rows
    if (i !== pivot) {
        [mat[i], mat[pivot]] = [mat[pivot], mat[i]];
        det *= -1;
    }

    det *= mat[i][i];

    // Eliminate below
    for (let j = i + 1; j < n; j++) {
        let factor = mat[j][i] / mat[i][i];
        for (let k = i; k < n; k++) {
            mat[j][k] -= factor * mat[i][k];
        }
    }
}

return det;

}

// Function to compute number of spanning trees // using adjacency matrix function numOfSpanningTree(graph, v) {

// Laplacian matrix
let L = Array.from({ length: v }, () => Array(v).fill(0));

for (let i = 0; i < v; i++) {
    let degree = 0;

    for (let j = 0; j < v; j++) {
        if (graph[i][j] === 1) {
            degree++;
            if (i !== j) L[i][j] = -1;
        }
    }

    L[i][i] = degree;
}

// Minor matrix
let minor = Array.from({ length: v - 1 }, () =>
    Array(v - 1).fill(0)
);

for (let i = 0; i < v - 1; i++) {
    for (let j = 0; j < v - 1; j++) {
        minor[i][j] = L[i][j];
    }
}

// Determinant
return Math.round(determinant(minor, v - 1));

}

// Driver code let v = 4;

let graph = [ [0, 1, 1, 1], [1, 0, 1, 1], [1, 1, 0, 1], [1, 1, 1, 0] ];

console.log(numOfSpanningTree(graph, v)); // Output: 16

`

**Time Complexity: O(n^3) due to Gaussian elimination for determinant.
**Auxiliary Space : O(n^2) for storing matrices.