 GeeksforGeeks App
Open App Browser
Continue

# Java Program to Check if a Steiner Tree of Size k Exists for a Graph

A Steiner tree is a tree that connects a subset of the vertices in a graph with the minimum total weight. It is often used to find the shortest path between a set of points in a graph. Here is a Java program to check if a Steiner tree of size k exists for a given graph:

## Java

 `import` `java.util.ArrayList;``import` `java.util.List;`` ` `public` `class` `SteinerTree {`` ` `    ``private` `static` `final` `int` `INF = Integer.MAX_VALUE;`` ` `    ``// Function to check if a Steiner tree of size k exists``    ``// for the given graph``    ``public` `static` `boolean` `checkSteinerTree(``int``[][] graph,``                                           ``int` `k)``    ``{``        ``int` `n = graph.length;``        ``int``[][] dp = ``new` `int``[n][``1` `<< n];`` ` `        ``// Initialize the dp array with INF``        ``for` `(``int` `i = ``0``; i < n; i++) {``            ``for` `(``int` `j = ``0``; j < (``1` `<< n); j++) {``                ``dp[i][j] = INF;``            ``}``        ``}`` ` `        ``// Set the base case where the tree consists of only``        ``// one vertex``        ``for` `(``int` `i = ``0``; i < n; i++) {``            ``dp[i][``1` `<< i] = ``0``;``        ``}`` ` `        ``// Iterate through all possible tree sizes``        ``for` `(``int` `mask = ``1``; mask < (``1` `<< n); mask++) {``            ``// Iterate through all possible root vertices``            ``for` `(``int` `root = ``0``; root < n; root++) {``                ``// Check if the root vertex is present in``                ``// the tree``                ``if` `((mask & (``1` `<< root)) == ``0``) {``                    ``continue``;``                ``}`` ` `                ``// Iterate through all possible subtrees``                ``for` `(``int` `submask = mask; submask > ``0``;``                     ``submask = (submask - ``1``) & mask) {``                    ``// Check if the current subtree is valid``                    ``// (i.e., non-empty)``                    ``if` `(submask == ``0``) {``                        ``continue``;``                    ``}`` ` `                    ``// Find the minimum weight of the``                    ``// current subtree``                    ``int` `minWeight = INF;``                    ``for` `(``int` `i = ``0``; i < n; i++) {``                        ``// Check if the current vertex is``                        ``// present in the subtree``                        ``if` `((submask & (``1` `<< i)) == ``0``) {``                            ``continue``;``                        ``}`` ` `                        ``// Find the minimum weight of the``                        ``// current subtree``                        ``for` `(``int` `j = ``0``; j < n; j++) {``                            ``// Check if the current vertex``                            ``// is present in the subtree``                            ``if` `((submask & (``1` `<< j)) == ``0``) {``                                ``continue``;``                            ``}`` ` `                            ``// Update the minimum weight of``                            ``// the current subtree``                            ``minWeight = Math.min(``                                ``minWeight, graph[i][j]);``                        ``}``                    ``}`` ` `                    ``// Update the minimum weight of the``                    ``// current tree``                    ``dp[root][mask] = Math.min(``                        ``dp[root][mask],``                        ``dp[root][submask] + minWeight);``                ``}``            ``}``        ``}`` ` `        ``// Check if a Steiner tree of size k exists``        ``for` `(``int` `i = ``0``; i < n; i++) {``            ``if` `(dp[i][(``1` `<< n) - ``1``] <= k) {``                ``return` `true``;``            ``}``        ``}`` ` `        ``return` `false``;``    ``}`` ` `    ``public` `static` `void` `main(String[] args)``    ``{ ``// Test with a sample graph``        ``int``[][] graph = { { ``0``, ``1``, ``3``, INF, INF },``                          ``{ ``1``, ``0``, ``3``, ``6``, INF },``                          ``{ ``3``, ``3``, ``0``, ``4``, ``2` `},``                          ``{ INF, ``6``, ``4``, ``0``, ``5` `},``                          ``{ INF, INF, ``2``, ``5``, ``0` `} };``        ``int` `k = ``8``;``        ``System.out.println(checkSteinerTree(``            ``graph, k)); ``// Expected output: true``    ``}``}`

Time complexity of O((3^n) * n^2), where n is the number of vertices in the graph. This can be quite slow for large graphs.

Output:

`true`

Explanation:

The algorithm uses dynamic programming to find the minimum weight of a Steiner tree for each possible tree size and root vertex. It uses a two-dimensional dp array, where dp[i][j] represents the minimum weight of a Steiner tree rooted at vertex i and consisting of the vertices in the set represented by j (in binary).

First, the dp array is initialized with INF for all entries. Then, the base case where the tree consists of only one vertex is set. For each possible tree size, the algorithm iterates through all possible root vertices and checks if the root is present in the tree (by checking if the corresponding bit in the mask is set). If the root is present, the algorithm iterates through all possible subtrees and finds the minimum weight of the current subtree. Then, it updates the minimum weight of the current tree by adding the minimum weight of the current subtree to the minimum weight of the current tree rooted at the same vertex and consisting of the vertices in the subtree.

Finally, the algorithm checks if a Steiner tree of size k exists by checking if the minimum weight of any tree rooted at any vertex and consisting of all vertices is less than or equal to k. If such a tree exists, the function returns true; otherwise, it returns false.

In the sample test case, the graph is a complete graph with 5 vertices and the following edge weights:

```  0  1  3
1 0  1  3
3 1  0  3
4 3  3  0
5   6  4  2
2  5  0```

A Steiner tree of size 8 can be obtained by taking the minimum weight edge from each subtree, as shown below:

```  0  1  3
1 0  1  3
3   1  0
4 3  3  0
2  5  0```

The minimum weight of this Steiner tree is 8, which is equal to the given value of k, so the function returns true.

My Personal Notes arrow_drop_up