Maximum value of a Node that can be reached using given connections
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);
10
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
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) , v is the number of vertices
Related Articles:
- Introduction to Graph – Data Structures and Algorithms Tutorials
- Depth First Search or DFS for a Graph
Please Login to comment...