Given an undirected unweighted connected graph consisting of n vertices and m edges. The task is to find any spanning tree of this graph such that the maximum degree over all vertices is maximum possible. The order in which you print the output edges does not matter and an edge can be printed in reverse also i.e. (u, v) can also be printed as (v, u).
Examples:
Input:
1
/ \
2 5
\ /
3
|
4
Output:
3 2
3 5
3 4
1 2
The maximum degree over all vertices
is of vertex 3 which is 3 and is
maximum possible.
Input:
1
/
2
/ \
5 3
|
4
Output:
2 1
2 5
2 3
3 4
Prerequisite: Kruskal Algorithm to find Minimum Spanning Tree
Approach: The given problem can be solved using Kruskal’s algorithm to find the Minimum Spanning tree.
We find the vertex which has maximum degree in the graph. At first we will perform the union of all the edges which are incident to this vertex and then carry out normal Kruskal’s algorithm. This gives us optimal spanning tree.
C++
#include<bits/stdc++.h>
using namespace std;
vector< int > par,sz;
int find( int x)
{
if (par[x]!=x)
par[x]=find(par[x]);
return par[x];
}
void Union( int u, int v)
{
int x = find(u);
int y = find(v);
if (x == y)
return ;
if (sz[x] > sz[y])
par[y] = x;
else if (sz[x] < sz[y])
par[x] = y;
else {
par[x] = y;
sz[y]++;
}
}
void findSpanningTree(vector< int > deg, int n, int m,vector<vector< int >> g)
{
par.resize(n+1);
sz.resize(n+1);
for ( int i = 1; i <= n; i++)
par[i] = i;
int max = 1;
for ( int i = 2; i <= n; i++)
if (deg[i] > deg[max])
max = i;
for ( int v : g[max]) {
cout << max << " " << v << '\n' ;
Union(max, v);
}
for ( int u = 1; u <= n; u++) {
for ( int v : g[u]) {
int x = find(u);
int y = find(v);
if (x == y)
continue ;
Union(x, y);
cout << u << " " << v << '\n' ;
}
}
}
int main()
{
int n = 5;
int m = 5;
vector<vector< int >> g(n+1);
vector< int > deg(n+1);
g[1].push_back(2);
g[2].push_back(1);
deg[1]++;
deg[2]++;
g[1].push_back(5);
g[5].push_back(1);
deg[1]++;
deg[5]++;
g[2].push_back(3);
g[3].push_back(2);
deg[2]++;
deg[3]++;
g[5].push_back(3);
g[3].push_back(5);
deg[3]++;
deg[5]++;
g[3].push_back(4);
g[4].push_back(3);
deg[3]++;
deg[4]++;
findSpanningTree(deg, n, m, g);
return 0;
}
|
Java
import java.util.*;
public class GFG {
static int par[], rank[];
static int find( int x)
{
if (par[x] != x)
par[x] = find(par[x]);
return par[x];
}
static void union( int u, int v)
{
int x = find(u);
int y = find(v);
if (x == y)
return ;
if (rank[x] > rank[y])
par[y] = x;
else if (rank[x] < rank[y])
par[x] = y;
else {
par[x] = y;
rank[y]++;
}
}
static void findSpanningTree( int deg[], int n,
int m, ArrayList<Integer> g[])
{
par = new int [n + 1 ];
rank = new int [n + 1 ];
for ( int i = 1 ; i <= n; i++)
par[i] = i;
int max = 1 ;
for ( int i = 2 ; i <= n; i++)
if (deg[i] > deg[max])
max = i;
for ( int v : g[max]) {
System.out.println(max + " " + v);
union(max, v);
}
for ( int u = 1 ; u <= n; u++) {
for ( int v : g[u]) {
int x = find(u);
int y = find(v);
if (x == y)
continue ;
union(x, y);
System.out.println(u + " " + v);
}
}
}
public static void main(String args[])
{
int n = 5 ;
int m = 5 ;
ArrayList<Integer> g[] = new ArrayList[n + 1 ];
for ( int i = 1 ; i <= n; i++)
g[i] = new ArrayList<>();
int deg[] = new int [n + 1 ];
g[ 1 ].add( 2 );
g[ 2 ].add( 1 );
deg[ 1 ]++;
deg[ 2 ]++;
g[ 1 ].add( 5 );
g[ 5 ].add( 1 );
deg[ 1 ]++;
deg[ 5 ]++;
g[ 2 ].add( 3 );
g[ 3 ].add( 2 );
deg[ 2 ]++;
deg[ 3 ]++;
g[ 5 ].add( 3 );
g[ 3 ].add( 5 );
deg[ 3 ]++;
deg[ 5 ]++;
g[ 3 ].add( 4 );
g[ 4 ].add( 3 );
deg[ 3 ]++;
deg[ 4 ]++;
findSpanningTree(deg, n, m, g);
}
}
|
Python3
from typing import List
par = []
rnk = []
def find(x: int ) - > int :
global par
if (par[x] ! = x):
par[x] = find(par[x])
return par[x]
def Union(u: int , v: int ) - > None :
global par, rnk
x = find(u)
y = find(v)
if (x = = y):
return
if (rnk[x] > rnk[y]):
par[y] = x
elif (rnk[x] < rnk[y]):
par[x] = y
else :
par[x] = y
rnk[y] + = 1
def findSpanningTree(deg: List [ int ], n: int , m: int ,
g: List [ List [ int ]]) - > None :
global rnk, par
par = [i for i in range (n + 1 )]
rnk = [ 0 ] * (n + 1 )
max = 1
for i in range ( 2 , n + 1 ):
if (deg[i] > deg[ max ]):
max = i
for v in g[ max ]:
print ( "{} {}" . format ( max , v))
Union( max , v)
for u in range ( 1 , n + 1 ):
for v in g[u]:
x = find(u)
y = find(v)
if (x = = y):
continue
Union(x, y)
print ( "{} {}" . format (u, v))
if __name__ = = "__main__" :
n = 5
m = 5
g = [[] for _ in range (n + 1 )]
deg = [ 0 ] * (n + 1 )
g[ 1 ].append( 2 )
g[ 2 ].append( 1 )
deg[ 1 ] + = 1
deg[ 2 ] + = 1
g[ 1 ].append( 5 )
g[ 5 ].append( 1 )
deg[ 1 ] + = 1
deg[ 5 ] + = 1
g[ 2 ].append( 3 )
g[ 3 ].append( 2 )
deg[ 2 ] + = 1
deg[ 3 ] + = 1
g[ 5 ].append( 3 )
g[ 3 ].append( 5 )
deg[ 3 ] + = 1
deg[ 5 ] + = 1
g[ 3 ].append( 4 )
g[ 4 ].append( 3 )
deg[ 3 ] + = 1
deg[ 4 ] + = 1
findSpanningTree(deg, n, m, g)
|
C#
using System;
using System.Collections.Generic;
class GFG
{
static int []par;
static int []rank;
static int find( int x)
{
if (par[x] != x)
par[x] = find(par[x]);
return par[x];
}
static void union( int u, int v)
{
int x = find(u);
int y = find(v);
if (x == y)
return ;
if (rank[x] > rank[y])
par[y] = x;
else if (rank[x] < rank[y])
par[x] = y;
else {
par[x] = y;
rank[y]++;
}
}
static void findSpanningTree( int []deg, int n,
int m, List< int > []g)
{
par = new int [n + 1];
rank = new int [n + 1];
for ( int i = 1; i <= n; i++)
par[i] = i;
int max = 1;
for ( int i = 2; i <= n; i++)
if (deg[i] > deg[max])
max = i;
foreach ( int v in g[max])
{
Console.WriteLine(max + " " + v);
union(max, v);
}
for ( int u = 1; u <= n; u++)
{
foreach ( int v in g[u])
{
int x = find(u);
int y = find(v);
if (x == y)
continue ;
union(x, y);
Console.WriteLine(u + " " + v);
}
}
}
public static void Main(String []args)
{
int n = 5;
int m = 5;
List< int > []g = new List< int >[n + 1];
for ( int i = 1; i <= n; i++)
g[i] = new List< int >();
int []deg = new int [n + 1];
g[1].Add(2);
g[2].Add(1);
deg[1]++;
deg[2]++;
g[1].Add(5);
g[5].Add(1);
deg[1]++;
deg[5]++;
g[2].Add(3);
g[3].Add(2);
deg[2]++;
deg[3]++;
g[5].Add(3);
g[3].Add(5);
deg[3]++;
deg[5]++;
g[3].Add(4);
g[4].Add(3);
deg[3]++;
deg[4]++;
findSpanningTree(deg, n, m, g);
}
}
|
Javascript
<script>
let par, rank;
function find(x)
{
if (par[x] != x)
par[x] = find(par[x]);
return par[x];
}
function union(u, v)
{
let x = find(u);
let y = find(v);
if (x == y)
return ;
if (rank[x] > rank[y])
par[y] = x;
else if (rank[x] < rank[y])
par[x] = y;
else {
par[x] = y;
rank[y]++;
}
}
function findSpanningTree(deg, n, m, g)
{
par = new Array(n + 1);
rank = new Array(n + 1);
for (let i = 1; i <= n; i++)
par[i] = i;
let max = 1;
for (let i = 2; i <= n; i++)
if (deg[i] > deg[max])
max = i;
for (let v = 0; v < g[max].length; v++) {
document.write(max + " " + g[max][v] + "</br>" );
union(max, g[max][v]);
}
for (let u = 1; u <= n; u++) {
for (let v = 0; v < g[u].length; v++) {
let x = find(u);
let y = find(g[u][v]);
if (x == y)
continue ;
union(x, y);
document.write(u + " " + g[u][v] + "</br>" );
}
}
}
let n = 5;
let m = 5;
let g = new Array(n + 1);
for (let i = 1; i <= n; i++)
g[i] = [];
let deg = new Array(n + 1);
deg.fill(0);
g[1].push(2);
g[2].push(1);
deg[1]++;
deg[2]++;
g[1].push(5);
g[5].push(1);
deg[1]++;
deg[5]++;
g[2].push(3);
g[3].push(2);
deg[2]++;
deg[3]++;
g[5].push(3);
g[3].push(5);
deg[3]++;
deg[5]++;
g[3].push(4);
g[4].push(3);
deg[3]++;
deg[4]++;
findSpanningTree(deg, n, m, g);
</script>
|
Time Complexity: O(N * logN), where N is the total number of nodes in the graph.
Auxiliary Space: O(N)