Maximum value of a Node that can be reached using given connections
Last Updated :
14 Mar, 2023
Given a set of 109 nodes. There are N bidirectional connections, and ith connection connects the Aith​ and Bith​ nodes. Starting from the first node, find the maximum value of a node that can be reached using given connections.
Examples:
Input: N = 4
1 4
4 6
4 10
7 3
Output: 10
Explanation: Move from 1st node to 4th node using connection 1, then move to 10th node from 4th node using connection 3.
Input: N = 3
5 6
6 70
70 800
Output: 1
Explanation: You are initially on node 1 and there is no connection from the 1st node so you can’t reach anywhere.
Approach: The problem can be solved using DFS based on the following idea.
The idea/intuition is to start from 1st node and check the nodes we can reach from it directly or through any connected path. Build a graph of nodes where connections connect any two floors, then run dfs and update maximum at each step.
Follow the steps mentioned below to implement the idea:
- Make an unordered map for marking connections between the nodes.
- Make a set, which will tell whether the node is visited before in dfs traversal.
- Start dfs traversal from node 1, mark the current node as visited in the set and update maximum with the current node.
- Traverse in all child nodes of the current node, if the child node is not visited call dfs for the child node.
- At last, when all connected nodes are traversed, we have the maximum node reachable in res.
Below is the implementation of the above approach.
C++
// C++ code to implement the approach
#include <bits/stdc++.h>
using namespace std;
// Utility function to add edge
// between node u and v
void addEdge(map<int, vector<int> >& adj, int u, int v)
{
adj[u].push_back(v);
adj[v].push_back(u);
}
// Global variable to store max
// reachable node
int res = 1;
// DFS function to traverse the graph
void dfs(map<int, vector<int> >& adj, set<int>& vis,
int root)
{
// Mark the root node as visited
vis.insert(root);
// Update res with maximum of res
// and current node
res = max(res, root);
// Traverse in child nodes
for (int child : adj[root]) {
// If it's not visited
if (vis.find(child) == vis.end())
dfs(adj, vis, child);
}
}
// Driver Code
int main()
{
int n = 4;
// Adjacency list for storing graph
map<int, vector<int> > adj;
// Taking n connections input
addEdge(adj, 1, 4);
addEdge(adj, 4, 6);
addEdge(adj, 4, 10);
addEdge(adj, 7, 3);
// Set to mark visited node
set<int> vis;
// dfs call with initial node 1
dfs(adj, vis, 1);
cout << res;
return 0;
}
Java
// Java code to implement the approach
import java.io.*;
import java.util.*;
import java.util.HashMap;
public class GFG {
// Utility function to add edge
// between node u and v
static void addEdge(HashMap<Integer, ArrayList<Integer>> adj, Integer u, Integer v)
{
if(adj.containsKey(u))
adj.get(u).add(v);
else{
adj.put(u,new ArrayList<Integer>());
adj.get(u).add(v);
}
if(adj.containsKey(v))
adj.get(v).add(u);
else{
adj.put(v,new ArrayList<Integer>());
adj.get(v).add(u);
}
}
// Global variable to store max
// reachable node
static Integer res = 1;
// DFS function to traverse the graph
static void dfs(HashMap<Integer, ArrayList<Integer>> adj, Set<Integer> vis,
Integer root)
{
// Mark the root node as visited
vis.add(root);
// Update res with maximum of res
// and current node
res = Math.max(res, root);
// Traverse in child nodes
if(adj.containsKey(root))
{
for(int i=0;i<adj.get(root).size();i++)
{
// If it's not visited
if(vis.contains(adj.get(root).get(i))==false)
{ Integer child=adj.get(root).get(i);
dfs(adj, vis, child);
}
}
}
}
// Driver Code
public static void main(String[] args)
{
int n = 4;
// Adjacency list for storing graph
HashMap<Integer, ArrayList<Integer>> adj = new HashMap<>();
// Taking n connections input
addEdge(adj, 1, 4);
addEdge(adj, 4, 6);
addEdge(adj, 4, 10);
addEdge(adj, 7, 3);
// Set to mark visited node
Set<Integer> vis = new HashSet<Integer>();
// dfs call with initial node 1
dfs(adj, vis, 1);
System.out.println(res);
}
}
// This code is contributed by Pushpesh Raj.
Python3
# python code implementation
from collections import defaultdict
# Utility function to add edge
# between node u and v
def addEdge(adj, u, v):
adj[u].append(v)
adj[v].append(u)
# Global variable to store max
# reachable node
res = 1
# DFS function to traverse the graph
def dfs(adj, vis, root):
# Mark the root node as visited
vis.add(root)
# Update res with maximum of res
# and current node
global res
res = max(res, root)
# Traverse in child nodes
for child in adj[root]:
# If it's not visited
if child not in vis:
dfs(adj, vis, child)
# Driver Code
if __name__ == "__main__":
n = 4
# Adjacency list for storing graph
adj = defaultdict(list)
# Taking n connections input
addEdge(adj, 1, 4)
addEdge(adj, 4, 6)
addEdge(adj, 4, 10)
addEdge(adj, 7, 3)
# Set to mark visited node
vis = set()
# dfs call with initial node 1
dfs(adj, vis, 1)
print(res)
# This code is contributed by ksam24000
C#
using System;
using System.Collections.Generic;
class MainClass {
// Utility function to add edge
// between node u and v
static void addEdge(Dictionary<int, List<int> > adj,
int u, int v)
{
if (!adj.ContainsKey(u)) {
adj[u] = new List<int>();
}
adj[u].Add(v);
if (!adj.ContainsKey(v)) {
adj[v] = new List<int>();
}
adj[v].Add(u);
}
// Global variable to store max
// reachable node
static int res = 1;
// DFS function to traverse the graph
static void dfs(Dictionary<int, List<int> > adj,
HashSet<int> vis, int root)
{
// Mark the root node as visited
vis.Add(root);
// Update res with maximum of res
// and current node
res = Math.Max(res, root);
// Traverse in child nodes
if (adj.ContainsKey(root)) {
foreach(int child in adj[root])
{
// If it's not visited
if (!vis.Contains(child)) {
dfs(adj, vis, child);
}
}
}
}
// Driver Code
public static void Main(string[] args)
{
int n = 4;
// Adjacency list for storing graph
Dictionary<int, List<int> > adj
= new Dictionary<int, List<int> >();
// Taking n connections input
addEdge(adj, 1, 4);
addEdge(adj, 4, 6);
addEdge(adj, 4, 10);
addEdge(adj, 7, 3);
// Set to mark visited node
HashSet<int> vis = new HashSet<int>();
// dfs call with initial node 1
dfs(adj, vis, 1);
Console.WriteLine(res);
}
}
Javascript
let adj = new Map();
let vis = new Set();
let res = 1;
function addEdge(adj, u, v) {
if (!adj.has(u)) {
adj.set(u, []);
}
if (!adj.has(v)) {
adj.set(v, []);
}
adj.get(u).push(v);
adj.get(v).push(u);
}
function dfs(adj, vis, root) {
vis.add(root);
res = Math.max(res, root);
for (let child of adj.get(root)) {
if (!vis.has(child)) {
dfs(adj, vis, child);
}
}
}
addEdge(adj, 1, 4);
addEdge(adj, 4, 6);
addEdge(adj, 4, 10);
addEdge(adj, 7, 3);
dfs(adj, vis, 1);
console.log(res);
Output:
10
Time complexity: O(V + E), where V is the number of vertices and E is the number of edges in the graph.
Auxiliary Space: O(V), since an extra visited array of size V is required.
Approach (Using BFS):
1. Make an Adjanceny list to store the graph
2. Create a set, which will tell whether the node is visited before in dfs traversal.
3. Start BFS traversal from node 1, mark the current node as visited in the set and update maximum with the current node. Create a Queue
4. Traverse in all child(adjacent) nodes of the current node, if the child node is not visited add it into the queue
5. At last, when all connected nodes are traversed, we have the maximum node reachable in res.
Below is the implementation of the above approach.
C++
#include <iostream>
#include <unordered_map>
#include <vector>
#include <queue>
#include <unordered_set>
using namespace std;
// Utility function to add edge between node u and v
void addEdge(unordered_map<int, vector<int>>& adj, int u, int v) {
if (adj.find(u) != adj.end())
adj[u].push_back(v);
else {
adj[u] = vector<int>();
adj[u].push_back(v);
}
if (adj.find(v) != adj.end())
adj[v].push_back(u);
else {
adj[v] = vector<int>();
adj[v].push_back(u);
}
}
int res = 1;
int max_node_value(unordered_map<int, vector<int>>& adj) {
// creating an unordered_set to store visited nodes
unordered_set<int> visited;
visited.insert(res);
// Adding 1 because we are starting from there
// Update the res with maximum of res and current node
queue<int> q;
q.push(1);
while (!q.empty()) {
int curr = q.front();
q.pop();
visited.insert(curr);
// Update res with maximum of res and current node
res = max(res, curr);
for (int x : adj[curr])
if (visited.find(x) == visited.end())
q.push(x);
}
return res;
}
int main() {
int n = 4;
// Adjacency list for storing graph
unordered_map<int, vector<int>> adj;
// Taking n connections input
addEdge(adj, 1, 4);
addEdge(adj, 4, 6);
addEdge(adj, 4, 10);
addEdge(adj, 7, 3);
// bfs call
max_node_value(adj);
cout << res << endl;
return 0;
}
Java
import java.util.*;
class Main {
// Utility function to add edge
// between node u and v
static void
addEdge(HashMap<Integer, ArrayList<Integer> > adj,
Integer u, Integer v)
{
if (adj.containsKey(u))
adj.get(u).add(v);
else {
adj.put(u, new ArrayList<Integer>());
adj.get(u).add(v);
}
if (adj.containsKey(v))
adj.get(v).add(u);
else {
adj.put(v, new ArrayList<Integer>());
adj.get(v).add(u);
}
}
static int res = 1;
public static int max_node_value(
HashMap<Integer, ArrayList<Integer> > adj)
{
// creating a hashset to store visited nodes
HashSet<Integer> visited = new HashSet<>();
visited.add(res);
// Adding 1 because we are
// starting from there
// Update the res with maximum of res
// and current node
Queue<Integer> queue = new LinkedList<>();
queue.add(1);
while (!queue.isEmpty()) {
int curr = queue.poll();
visited.add(curr);
// Update res with maximum of res
// and current node
res = Math.max(res, curr);
for (int x : adj.get(curr))
if (!visited.contains(x))
queue.add(x);
}
return res;
}
public static void main(String[] args)
{
int n = 4;
// Adjacency list for storing graph
HashMap<Integer, ArrayList<Integer> > adj
= new HashMap<>();
// Taking n connections input
addEdge(adj, 1, 4);
addEdge(adj, 4, 6);
addEdge(adj, 4, 10);
addEdge(adj, 7, 3);
// bfs call
max_node_value(adj);
System.out.println(res);
}
}
Python3
import collections
# Utility function to add edge between node u and v
def addEdge(adj, u, v):
if u in adj:
adj[u].append(v)
else:
adj[u] = [v]
if v in adj:
adj[v].append(u)
else:
adj[v] = [u]
res = 1
def max_node_value(adj):
global res
# creating an unordered_set to store visited nodes
visited = set()
visited.add(res)
# Adding 1 because we are starting from there
# Update the res with maximum of res and current node
q = collections.deque([1])
while q:
curr = q.popleft()
visited.add(curr)
# Update res with maximum of res and current node
res = max(res, curr)
for x in adj[curr]:
if x not in visited:
q.append(x)
return res
# Adjacency list for storing graph
adj = {}
# Taking n connections input
addEdge(adj, 1, 4)
addEdge(adj, 4, 6)
addEdge(adj, 4, 10)
addEdge(adj, 7, 3)
# bfs call
max_node_value(adj)
print(res)
# This code is contributed by Akash Jha
C#
using System;
using System.Collections.Generic;
class MainClass {
// Utility function to add edge
// between node u and v
static void AddEdge(Dictionary<int, List<int> > adj,
int u, int v)
{
if (adj.ContainsKey(u))
adj[u].Add(v);
else {
adj.Add(u, new List<int>());
adj[u].Add(v);
}
if (adj.ContainsKey(v))
adj[v].Add(u);
else {
adj.Add(v, new List<int>());
adj[v].Add(u);
}
}
static int res = 1;
public static int
MaxNodeValue(Dictionary<int, List<int> > adj)
{
// creating a hashset to store visited nodes
HashSet<int> visited = new HashSet<int>();
visited.Add(res);
// Adding 1 because we are
// starting from there
// Update the res with maximum of res
// and current node
Queue<int> queue = new LinkedList<int>();
queue.Enqueue(1);
while (queue.Count > 0) {
int curr = queue.Dequeue();
visited.Add(curr);
// Update res with maximum of res
// and current node
res = Math.Max(res, curr);
foreach(int x in
adj[curr]) if (!visited.Contains(x))
queue.Enqueue(x);
}
return res;
}
public static void Main(string[] args)
{
int n = 4;
// Adjacency list for storing graph
Dictionary<int, List<int> > adj
= new Dictionary<int, List<int> >();
// Taking n connections input
AddEdge(adj, 1, 4);
AddEdge(adj, 4, 6);
AddEdge(adj, 4, 10);
AddEdge(adj, 7, 3);
// bfs call
MaxNodeValue(adj);
Console.WriteLine(res);
}
}
Javascript
// Utility function to add edge between node u and v
function addEdge(adj, u, v) {
if (adj.has(u))
adj.get(u).push(v);
else {
adj.set(u, []);
adj.get(u).push(v);
}
if (adj.has(v))
adj.get(v).push(u);
else {
adj.set(v, []);
adj.get(v).push(u);
}
}
let res = 1;
function max_node_value(adj) {
// creating an unordered_set to store visited nodes
let visited = new Set();
visited.add(res);
// Adding 1 because we are starting from there
// Update the res with maximum of res and current node
let q = [];
q.push(1);
while (q.length !== 0) {
let curr = q.shift();
visited.add(curr);
// Update res with maximum of res and current node
res = Math.max(res, curr);
for (let x of adj.get(curr))
if (!visited.has(x))
q.push(x);
}
return res;
}
// Adjacency list for storing graph
let adj = new Map();
// Taking n connections input
addEdge(adj, 1, 4);
addEdge(adj, 4, 6);
addEdge(adj, 4, 10);
addEdge(adj, 7, 3);
// bfs call
max_node_value(adj);
console.log(res);
// This code is contributed by Prajwal Kandekar
Time complexity: O(V + E), where V is the number of vertices and E is the number of edges in the graph.
Auxiliary Space: O(V) , v is the number of vertices
Related Articles:
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...