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++
// 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 graphvector<int> gr[N], dis[2];bool vis[N];int colour[N];bool bip;Â
// Function to add edgevoid Add_edge(int x, int y){Â Â Â Â gr[x].push_back(y);Â Â Â Â gr[y].push_back(x);}Â
// Bipartite functionvoid 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 graphvoid 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 codeint 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
// 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 |
Python3
# Python 3 program to find two disjoint# good sets of vertices in a given graphN = 100005Â
# For the graphgr = [[] 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 edgedef Add_edge(x, y):Â Â Â Â gr[x].append(y)Â Â Â Â gr[y].append(x)Â
# Bipartite functiondef 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 graphdef 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 codeif __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#
// 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 graphstatic 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 edgestatic void add_edge(int x, Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â int y){Â Â gr[x].Add(y);Â Â gr[y].Add(x);}Â
// Bipartite functionstatic 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 graphstatic 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 Codepublic 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 |
Javascript
<script>Â
// JavaScript program to find two // disjoint good sets of // vertices in a given graph Â
var N = 100005;Â
// For the graphvar 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 edgefunction add_edge(x, y){Â Â gr[x].push(y);Â Â gr[y].push(x);}Â
// Bipartite functionfunction 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 graphfunction 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 Codevar n = 6, m = 4;Â
// push edgesadd_edge(1, 2);add_edge(2, 3);add_edge(2, 4);add_edge(5, 6);// Function callgoodsets(n);Â
</script> |
1 3 4 5 2 6
Â
Time Complexity: O(n)
Space Complexity: O(n)
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 neveropen!

