Найдите путь от корня к заданным узлам дерева для нескольких запросов
Дано дерево с N вершинами, пронумерованными от 0 до N - 1 (0- й узел является корневым). Также, учитывая q запросов, содержащих узлы в дереве. Задача состоит в том, чтобы найти путь от корневого узла к заданному узлу для нескольких запросов.
Примеры:
Ввод: N = 6, q [] = {2, 4} Дерево: 0 / 1 2 | 3 / 4 5 Выход: 0 2 0 1 3 4 Путь от корневого узла к узлу 2 равен 0 -> 2. Путь от корневого узла к узлу 4: 0 -> 1 -> 3 -> 4.
Подход: путь от любой корневой вершины к любой вершине i - это путь от корневой вершины до ее родителя, за которым следует сам родитель. Это может быть достигнуто путем изменения обхода дерева в ширину. В списке путей для каждой непосещенной вершины добавьте копию пути ее родительского элемента в список, а затем добавьте родительский элемент в список.
Ниже представлена реализация описанного выше подхода:
C ++
// C++ implementation of the approach #include <bits/stdc++.h> using namespace std; const int sz = 1e5; // Adjacency list representation // of the tree vector< int > tree[sz]; // Boolean array to mark all the // vertices which are visited bool vis[sz]; // Array of vector where ith index // stores the path from the root // node to the ith node vector< int > path[sz]; // Utility function to create an // edge between two vertices void addEdge( int a, int b) { // Add a to b's list tree[a].push_back(b); // Add b to a's list tree[b].push_back(a); } // Modified Breadth-First Function void bfs( int node) { // Create a queue of {child, parent} queue<pair< int , int > > qu; // Push root node in the front of // the queue and mark as visited qu.push({ node, -1 }); vis[node] = true ; while (!qu.empty()) { pair< int , int > p = qu.front(); // Dequeue a vertex from queue qu.pop(); vis[p.first] = true ; // Get all adjacent vertices of the dequeued // vertex s. If any adjacent has not // been visited then enqueue it for ( int child : tree[p.first]) { if (!vis[child]) { qu.push({ child, p.first }); // Path from the root to this vertex is // the path from root to the parent // of this vertex followed by the // parent itself path[child] = path[p.first]; path[child].push_back(p.first); } } } } // Utility Function to print the // path from root to given node void displayPath( int node) { vector< int > ans = path[node]; for ( int k : ans) { cout << k << " " ; } cout << node << '
' ; } // Driver code int main() { // Number of vertices int n = 6; addEdge(0, 1); addEdge(0, 2); addEdge(1, 3); addEdge(3, 4); addEdge(3, 5); // Calling modified bfs function bfs(0); // Display paths from root vertex // to the given vertices displayPath(2); displayPath(4); displayPath(5); return 0; } |
Ява
// Java implementation of the approach import java.util.*; @SuppressWarnings ( "unchecked" ) class GFG { static class Pair<T, V> { T first; V second; Pair() { } Pair(T first, V second) { this .first = first; this .second = second; } } static int sz = ( int ) 1e5; // Adjacency list representation // of the tree static Vector<Integer>[] tree = new Vector[sz]; // Boolean array to mark all the // vertices which are visited static boolean [] vis = new boolean [sz]; // Array of vector where ith index // stores the path from the root // node to the ith node static Vector<Integer>[] path = new Vector[sz]; // Utility function to create an // edge between two vertices static void addEdge( int a, int b) { // Add a to b's list tree[a].add(b); // Add b to a's list tree[b].add(a); } // Modified Breadth-First Function static void bfs( int node) { // Create a queue of {child, parent} Queue<Pair<Integer, Integer>> qu = new LinkedList<>(); // Push root node in the front of // the queue and mark as visited qu.add( new Pair<>(node, - 1 )); vis[node] = true ; while (!qu.isEmpty()) { // Dequeue a vertex from queue Pair<Integer, Integer> p = qu.poll(); vis[p.first] = true ; // Get all adjacent vertices of the dequeued // vertex s. If any adjacent has not // been visited then enqueue it for ( int child : tree[p.first]) { if (!vis[child]) { qu.add( new Pair<>(child, p.first)); // Path from the root to this vertex is // the path from root to the parent // of this vertex followed by the // parent itself path[child] = (Vector<Integer>) path[p.first].clone(); path[child].add(p.first); } } } } // Utility Function to print the // path from root to given node static void displayPath( int node) { for ( int k : path[node]) { System.out.print(k + " " ); } System.out.println(node); } // Driver Code public static void main(String[] args) { for ( int i = 0 ; i < sz; i++) { tree[i] = new Vector<>(); path[i] = new Vector<>(); vis[i] = false ; } // Number of vertices int n = 6 ; addEdge( 0 , 1 ); addEdge( 0 , 2 ); addEdge( 1 , 3 ); addEdge( 3 , 4 ); addEdge( 3 , 5 ); // Calling modified bfs function bfs( 0 ); // Display paths from root vertex // to the given vertices displayPath( 2 ); displayPath( 4 ); displayPath( 5 ); } } // This code is contributed by // sanjeev2552 |
Python3
# Python3 implementation of the approach from collections import deque as queue sz = 7 # Adjacency list representation # of the tree tree = [[] for i in range (sz)] # Boolean array to mark all the # vertices which are visited vis = [ False ] * sz # Array of vector where ith index # stores the path from the root # node to the ith node path = [[] for i in range (sz)] # Utility function to create an # edge between two vertices def addEdge(a, b): # Add a to b's list tree[a].append(b) # Add b to a's list tree[b].append(a) # Modified Breadth-First Function def bfs(node): # Create a queue of {child, parent} qu = queue() # Push root node in the front of # the queue and mark as visited qu.append([node, - 1 ]) vis[node] = True while ( len (qu) > 0 ): p = qu.popleft() #print(p,p[0],p[1]) # Dequeue a vertex from queue # qu.pop() vis[p[ 0 ]] = True # Get all adjacent vertices of # the dequeued vertex s. If any # adjacent has not been visited # then enqueue it for child in tree[p[ 0 ]]: if (vis[child] = = False ): qu.append([child, p[ 0 ]]) # Path from the root to this # vertex is the path from root # to the parent of this vertex # followed by the parent itself for u in path[p[ 0 ]]: path[child].append(u) path[child].append(p[ 0 ]) #print(child,":",path[0]) # Utility Function to prthe # path from root to given node def displayPath(node): ans = path[node] for k in ans: print (k, end = " " ) print (node) # Driver code if __name__ = = '__main__' : # Number of vertices n = 6 addEdge( 0 , 1 ) addEdge( 0 , 2 ) addEdge( 1 , 3 ) addEdge( 3 , 4 ) addEdge( 3 , 5 ) # Calling modified bfs function bfs( 0 ) # Display paths from root vertex # to the given vertices displayPath( 2 ) displayPath( 4 ) displayPath( 5 ) # This code is contributed by mohit kumar 29 |
0 2 0 1 3 4 0 1 3 5
Вниманию читателя! Не прекращайте учиться сейчас. Освойте все важные концепции DSA с помощью самостоятельного курса DSA по доступной для студентов цене и будьте готовы к работе в отрасли. Чтобы завершить подготовку от изучения языка к DS Algo и многому другому, см. Полный курс подготовки к собеседованию .
Если вы хотите посещать живые занятия с отраслевыми экспертами, пожалуйста, обращайтесь к Geeks Classes Live и Geeks Classes Live USA.