# Find a set of at most N/2 nodes from a Graph such that all remaining nodes are directly connected to one of the chosen nodes

• Difficulty Level : Medium
• Last Updated : 15 Dec, 2021

Given an integer N, representing the number of nodes present in an undirected graph, with each node valued from 1 to N, and a 2D array Edges[][], representing the pair of vertices connected by an edge, the task is to find a set of at most N/2 nodes such that nodes that are not present in the set, are connected adjacent to any one of the nodes present in the set.

Examples :

Input: N = 4, Edges[] = {{2, 3}, {1, 3}, {4, 2}, {1, 2}}
Output: 3 2
Explanation: Connections specified in the above graph are as follows:
1
/       \
2   –   3
|
4
Selecting the set {2, 3} satisfies the required conditions.

Input: N = 5, Edges[] = {{2, 1}, {3, 1}, {3, 2}, {4, 1}, {4, 2}, {4, 3}, {5, 1}, {5, 2}, {5, 3}, {5, 4}}
Output: 1

Approach: The given problem can be solved based on the following observations:

• Assume a node to be the source node, then the distance of each vertex from the source node will be either odd or even.
• Split the nodes into two different sets based on parity, the size of at least one of the sets will not exceed N/2. Since each node of some parity is connected to at least one node of opposite parity, the criteria of choosing at most N/2 nodes is satisfied.

Follow the steps below to solve the problem:

• Assume any vertex to be the source node.
• Initialize two sets, say evenParity and oddParity, to store the nodes having even and odd distances from the source node respectively.
• Perform BFS Traversal on the given graph and split the vertices into two different sets depending on the parity of their distances from the source:
• After completing the above steps, print the elements of the set with the minimum size.

## C++

 `// C++ program for the above approach``#include ``using` `namespace` `std;` `// Function to add an edge``// to the adjacency list``void` `addEdge(vector >& adj,``             ``int` `u, ``int` `v)``{``    ``adj[u].push_back(v);``    ``adj[v].push_back(u);``}` `// Function to perform BFS``// traversal on a given graph``vector > BFS(``    ``int` `N, ``int` `source,``    ``vector > adjlist)``{``    ``// Stores the distance of each``    ``// node from the source node``    ``int` `dist[N + 1];` `    ``vector > vertex_set;` `    ``// Update the distance of all``    ``// vertices from source as -1``    ``memset``(dist, -1, ``sizeof` `dist);` `    ``// Assign two separate vectors``    ``// for parity odd and even parities``    ``vertex_set.assign(2, vector<``int``>(0));` `    ``// Perform BFS Traversal``    ``queue<``int``> Q;` `    ``// Push the source node``    ``Q.push(source);``    ``dist = 0;` `    ``// Iterate until queue becomes empty``    ``while` `(!Q.empty()) {` `        ``// Get the front node``        ``// present in the queue``        ``int` `u = Q.front();``        ``Q.pop();` `        ``// Push the node into vertex_set``        ``vertex_set[dist[u] % 2].push_back(u);` `        ``// Check if the adjacent``        ``// vertices are visited``        ``for` `(``int` `i = 0;``             ``i < (``int``)adjlist[u].size(); i++) {` `            ``// Adjacent node``            ``int` `v = adjlist[u][i];` `            ``// If the node v is unvisited``            ``if` `(dist[v] == -1) {` `                ``// Update the distance``                ``dist[v] = dist[u] + 1;` `                ``// Enqueue the node v``                ``Q.push(v);``            ``}``        ``}``    ``}` `    ``// Return the possible set of nodes``    ``return` `vertex_set;``}` `// Function to find a set of vertices``// of at most N/2 nodes such that each``// unchosen node is connected adjacently``// to one of the nodes in the set``void` `findSet(``int` `N,``             ``vector > adjlist)``{``    ``// Source vertex``    ``int` `source = 1;` `    ``// Store the vertex set``    ``vector > vertex_set``        ``= BFS(N, source, adjlist);` `    ``// Stores the index``    ``// with minimum size``    ``int` `in = 0;` `    ``if` `(vertex_set.size()``        ``< vertex_set.size())``        ``in = 1;` `    ``// Print the nodes present in the set``    ``for` `(``int` `node : vertex_set[in]) {``        ``cout << node << ``" "``;``    ``}``}` `// Driver Code``int` `main()``{``    ``int` `N = 5;``    ``int` `M = 8;``    ``vector > adjlist;``    ``adjlist.assign(N + 1, vector<``int``>(0));` `    ``// Graph Formation``    ``addEdge(adjlist, 2, 5);``    ``addEdge(adjlist, 2, 1);``    ``addEdge(adjlist, 5, 1);``    ``addEdge(adjlist, 4, 5);``    ``addEdge(adjlist, 1, 4);``    ``addEdge(adjlist, 2, 4);``    ``addEdge(adjlist, 3, 4);``    ``addEdge(adjlist, 3, 5);` `    ``// Function Call to print the``    ``// set of at most N / 2 nodes``    ``findSet(N, adjlist);` `    ``return` `0;``}`

## Python3

 `# Python3 program for the above approach``from` `collections ``import` `deque` `# Function to add an edge``# to the adjacency list``def` `addEdge(adj, u, v):``    ``adj[u].append(v)``    ``adj[v].append(u)``    ``return` `adj` `# Function to perform BFS``# traversal on a given graph``def` `BFS(N, source, adjlist):``  ` `    ``# Stores the distance of each``    ``# node from the source node``    ``dist ``=` `[``-``1``]``*``(N ``+` `1``)``    ``vertex_set ``=` `[[] ``for` `i ``in` `range``(``2``)]` `    ``# Perform BFS Traversal``    ``Q ``=` `deque()` `    ``# Push the source node``    ``Q.append(source)``    ``dist ``=` `0` `    ``# Iterate until queue becomes empty``    ``while` `len``(Q) > ``0``:` `        ``# Get the front node``        ``# present in the queue``        ``u ``=` `Q.popleft()` `        ``# Push the node into vertex_set``        ``vertex_set[dist[u] ``%` `2``].append(u)` `        ``# Check if the adjacent``        ``# vertices are visited``        ``for` `i ``in` `range``(``len``(adjlist[u])):``          ` `            ``# Adjacent node``            ``v ``=` `adjlist[u][i]` `            ``# If the node v is unvisited``            ``if` `(dist[v] ``=``=` `-``1``):` `                ``# Update the distance``                ``dist[v] ``=` `dist[u] ``+` `1` `                ``# Enqueue the node v``                ``Q.append(v)` `    ``# Return the possible set of nodes``    ``return` `vertex_set` `# Function to find a set of vertices``# of at most N/2 nodes such that each``# unchosen node is connected adjacently``# to one of the nodes in the set``def` `findSet(N, adjlist):``  ` `    ``# Source vertex``    ``source ``=` `1` `    ``# Store the vertex set``    ``vertex_set ``=` `BFS(N, source, adjlist)` `    ``# Stores the index``    ``# with minimum size``    ``inn ``=` `0` `    ``if` `(``len``(vertex_set[``1``]) < ``len``(vertex_set[``0``])):``        ``inn ``=` `1` `    ``# Print the nodes present in the set``    ``for` `node ``in` `vertex_set[inn]:``        ``print``(node, end``=``" "``)` `# Driver Code``if` `__name__ ``=``=` `'__main__'``:``    ``N ``=` `5``    ``M ``=` `8``    ``adjlist ``=` `[[] ``for` `i ``in` `range``(N``+``1``)]` `    ``# Graph Formation``    ``adjlist ``=` `addEdge(adjlist, ``2``, ``5``)``    ``adjlist ``=` `addEdge(adjlist, ``2``, ``1``)``    ``adjlist ``=` `addEdge(adjlist, ``5``, ``1``)``    ``adjlist ``=` `addEdge(adjlist, ``4``, ``5``)``    ``adjlist ``=` `addEdge(adjlist, ``1``, ``4``)``    ``adjlist ``=` `addEdge(adjlist, ``2``, ``4``)``    ``adjlist ``=` `addEdge(adjlist, ``3``, ``4``)``    ``adjlist ``=` `addEdge(adjlist, ``3``, ``5``)` `    ``# Function Call to print the``    ``# set of at most N / 2 nodes``    ``findSet(N, adjlist)` `# This code is contributed by mohit kumar 29.`
Output:
`1 3`

Time Complexity: O(N + M)
Auxiliary Space: O(N + M)

My Personal Notes arrow_drop_up