Given an undirected unweighted graph with N vertices and M edges. The task is to find two disjoint good sets of vertices. A set X is called good if for every edge UV in the graph at least one of the endpoint belongs to X(i.e, U or V or both U and V belong to X).
If it is not possible to make such sets then print -1.
Examples:
Input :
Output : {1 3 4 5} ,{2 6}
One disjoint good set contains vertices {1, 3, 4, 5} and other contains {2, 6}.Input :
Output : -1
Approach:
One of the observations is that there is no edge UV that U and V are in the same set. The two good sets form a bipartition of the graph, so the graph has to be bipartite. And being bipartite is also sufficient. Read about bipartition here.
Below is the implementation of the above approach :
// C++ program to find two disjoint // good sets of vertices in a given graph #include <bits/stdc++.h> using namespace std;
#define N 100005 // For the graph vector< int > gr[N], dis[2];
bool vis[N];
int colour[N];
bool bip;
// Function to add edge void Add_edge( int x, int y)
{ gr[x].push_back(y);
gr[y].push_back(x);
} // Bipartite function void dfs( int x, int col)
{ vis[x] = true ;
colour[x] = col;
// Check for child vertices
for ( auto i : gr[x]) {
// If it is not visited
if (!vis[i])
dfs(i, col ^ 1);
// If it is already visited
else if (colour[i] == col)
bip = false ;
}
} // Function to find two disjoint // good sets of vertices in a given graph void goodsets( int n)
{ // Initially assume that graph is bipartite
bip = true ;
// For every unvisited vertex call dfs
for ( int i = 1; i <= n; i++)
if (!vis[i])
dfs(i, 0);
// If graph is not bipartite
if (!bip)
cout << -1;
else {
// Differentiate two sets
for ( int i = 1; i <= n; i++)
dis[colour[i]].push_back(i);
// Print vertices belongs to both sets
for ( int i = 0; i < 2; i++) {
for ( int j = 0; j < dis[i].size(); j++)
cout << dis[i][j] << " " ;
cout << endl;
}
}
} // Driver code int main()
{ int n = 6, m = 4;
// Add edges
Add_edge(1, 2);
Add_edge(2, 3);
Add_edge(2, 4);
Add_edge(5, 6);
// Function call
goodsets(n);
} |
// Java program to find two disjoint // good sets of vertices in a given graph import java.util.*;
class GFG
{ static int N = 100005 ;
// For the graph
@SuppressWarnings ( "unchecked" )
static Vector<Integer>[] gr = new Vector[N],
dis = new Vector[ 2 ];
static
{
for ( int i = 0 ; i < N; i++)
gr[i] = new Vector<>();
for ( int i = 0 ; i < 2 ; i++)
dis[i] = new Vector<>();
}
static boolean [] vis = new boolean [N];
static int [] color = new int [N];
static boolean bip;
// Function to add edge
static void add_edge( int x, int y)
{
gr[x].add(y);
gr[y].add(x);
}
// Bipartite function
static void dfs( int x, int col)
{
vis[x] = true ;
color[x] = col;
// Check for child vertices
for ( int i : gr[x])
{
// If it is not visited
if (!vis[i])
dfs(i, col ^ 1 );
// If it is already visited
else if (color[i] == col)
bip = false ;
}
}
// Function to find two disjoint
// good sets of vertices in a given graph
static void goodsets( int n)
{
// Initially assume that graph is bipartite
bip = true ;
// For every unvisited vertex call dfs
for ( int i = 1 ; i <= n; i++)
if (!vis[i])
dfs(i, 0 );
// If graph is not bipartite
if (!bip)
System.out.println(- 1 );
else
{
// Differentiate two sets
for ( int i = 1 ; i <= n; i++)
dis[color[i]].add(i);
// Print vertices belongs to both sets
for ( int i = 0 ; i < 2 ; i++)
{
for ( int j = 0 ; j < dis[i].size(); j++)
System.out.print(dis[i].elementAt(j) + " " );
System.out.println();
}
}
}
// Driver Code
public static void main(String[] args)
{
int n = 6 , m = 4 ;
// Add edges
add_edge( 1 , 2 );
add_edge( 2 , 3 );
add_edge( 2 , 4 );
add_edge( 5 , 6 );
// Function call
goodsets(n);
}
} // This code is contributed by // sanjeev2552 |
# Python 3 program to find two disjoint # good sets of vertices in a given graph N = 100005
# For the graph gr = [[] for i in range (N)]
dis = [[] for i in range ( 2 )]
vis = [ False for i in range (N)]
colour = [ 0 for i in range (N)]
bip = 0
# Function to add edge def Add_edge(x, y):
gr[x].append(y)
gr[y].append(x)
# Bipartite function def dfs(x, col):
vis[x] = True
colour[x] = col
# Check for child vertices
for i in gr[x]:
# If it is not visited
if (vis[i] = = False ):
dfs(i, col ^ 1 )
# If it is already visited
elif (colour[i] = = col):
bip = False
# Function to find two disjoint # good sets of vertices in a given graph def goodsets(n):
# Initially assume that
# graph is bipartite
bip = True
# For every unvisited vertex call dfs
for i in range ( 1 , n + 1 , 1 ):
if (vis[i] = = False ):
dfs(i, 0 )
# If graph is not bipartite
if (bip = = 0 ):
print ( - 1 )
else :
# Differentiate two sets
for i in range ( 1 , n + 1 , 1 ):
dis[colour[i]].append(i)
# Print vertices belongs to both sets
for i in range ( 2 ):
for j in range ( len (dis[i])):
print (dis[i][j], end = " " )
print ( '\n' , end = "")
# Driver code if __name__ = = '__main__' :
n = 6
m = 4
# Add edges
Add_edge( 1 , 2 )
Add_edge( 2 , 3 )
Add_edge( 2 , 4 )
Add_edge( 5 , 6 )
# Function call
goodsets(n)
# This code is contributed # by Surendra_Gangwar |
// C# program to find two // disjoint good sets of // vertices in a given graph using System;
using System.Collections.Generic;
class GFG{
static int N = 100005;
// For the graph static List< int >[] gr =
new List< int >[N],
dis = new List< int >[2];
static bool [] vis = new bool [N];
static int [] color = new int [N];
static bool bip;
// Function to add edge static void add_edge( int x,
int y)
{ gr[x].Add(y);
gr[y].Add(x);
} // Bipartite function static void dfs( int x,
int col)
{ vis[x] = true ;
color[x] = col;
// Check for child vertices
foreach ( int i in gr[x])
{
// If it is not visited
if (!vis[i])
dfs(i, col ^ 1);
// If it is already visited
else if (color[i] == col)
bip = false ;
}
} // Function to find two disjoint // good sets of vertices in a // given graph static void goodsets( int n)
{ // Initially assume that
// graph is bipartite
bip = true ;
// For every unvisited
// vertex call dfs
for ( int i = 1; i <= n; i++)
if (!vis[i])
dfs(i, 0);
// If graph is not bipartite
if (!bip)
Console.WriteLine(-1);
else
{
// Differentiate two sets
for ( int i = 1;
i <= n; i++)
dis[color[i]].Add(i);
// Print vertices belongs
// to both sets
for ( int i = 0; i < 2; i++)
{
for ( int j = 0;
j < dis[i].Count; j++)
Console.Write(dis[i][j] + " " );
Console.WriteLine();
}
}
} // Driver Code public static void Main(String[] args)
{ int n = 6, m = 4;
for ( int i = 0; i < N; i++)
gr[i] = new List< int >();
for ( int i = 0; i < 2; i++)
dis[i] = new List< int >();
// Add edges
add_edge(1, 2);
add_edge(2, 3);
add_edge(2, 4);
add_edge(5, 6);
// Function call
goodsets(n);
} } // This code is contributed by shikhasingrajput |
<script> // JavaScript program to find two // disjoint good sets of // vertices in a given graph var N = 100005;
// For the graph var gr = Array.from(Array(N), ()=>Array());
var dis = Array.from(Array(2), ()=>Array());
var vis = Array(N).fill( false );
var color = Array(N).fill(0);
var bip;
// Function to add edge function add_edge(x, y)
{ gr[x].push(y);
gr[y].push(x);
} // Bipartite function function dfs(x, col)
{ vis[x] = true ;
color[x] = col;
// Check for child vertices
for ( var i of gr[x])
{
// If it is not visited
if (!vis[i])
dfs(i, col ^ 1);
// If it is already visited
else if (color[i] == col)
bip = false ;
}
} // Function to find two disjoint // good sets of vertices in a // given graph function goodsets(n)
{ // Initially assume that
// graph is bipartite
bip = true ;
// For every unvisited
// vertex call dfs
for ( var i = 1; i <= n; i++)
if (!vis[i])
dfs(i, 0);
// If graph is not bipartite
if (!bip)
document.write(-1 + "<br>" );
else
{
// Differentiate two sets
for ( var i = 1;
i <= n; i++)
dis[color[i]].push(i);
// Print vertices belongs
// to both sets
for ( var i = 0; i < 2; i++)
{
for ( var j = 0;
j < dis[i].length; j++)
document.write(dis[i][j] + " " );
document.write( "<br>" )
}
}
} // Driver Code var n = 6, m = 4;
// push edges add_edge(1, 2); add_edge(2, 3); add_edge(2, 4); add_edge(5, 6); // Function call goodsets(n); </script> |
1 3 4 5 2 6
Time Complexity: O(n)
Space Complexity: O(n)