 Open in App
Not now

# 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 : Hard
• 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
Related Articles