📌  相关文章
📜  查找多个查询中树到根节点的距离

📅  最后修改于: 2021-05-06 19:33:17             🧑  作者: Mango

给定一棵树,其中N个顶点的编号从0到N – 1,并且Q个查询包含树中的节点,任务是查找给定节点与根节点的距离,以进行多个查询。将第0个节点视为根节点,并将根节点与其自身的距离设为0。

例子:

Tree:
      0
     /  \
    1    2
    |   / \
    3  4   5
Input: 2
Output: 1
Explanation:
Distance of node 2 from root is 1

Input: 3
Output: 2
Explanation:
Distance of node 3 from root is 2

方法:
首先,将根节点的距离指定为0。然后,使用广度优先遍历(BFS)遍历树。将节点N的子节点标记为已访问时,还应将这些子节点的距离指定为distance [N] +1。最后,对于不同的查询,将打印该节点的距离数组的值。

下面是上述方法的实现:

C++
// C++ implementation for
// the above approach
#include 
using namespace std;
  
const int sz = 1e5;
  
// Adjacency list representation
// of the tree
vector tree[sz + 1];
  
// Boolean array to mark all the
// vertices which are visited
bool vis[sz + 1];
  
// Array of vector where ith index
// stores the path from the root
// node to the ith node
int dis[sz + 1];
  
// 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 > qu;
  
    // Push root node in the front of
    qu.push({ node, 0 });
    dis[0] = 0;
  
    while (!qu.empty()) {
        pair 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]) {
                dis[child] = dis[p.first] + 1;
                qu.push({ child, p.first });
            }
        }
    }
}
  
// Driver code
int main()
{
    // Number of vertices
    int n = 6;
  
    addEdge(0, 1);
    addEdge(0, 2);
    addEdge(1, 3);
    addEdge(2, 4);
    addEdge(2, 5);
  
    // Calling modified bfs function
    bfs(0);
  
    int q[] = { 2, 4 };
  
    for (int i = 0; i < 2; i++) {
        cout << dis[q[i]] << '\n';
    }
  
    return 0;
}


Java
// Java implementation for
// the above approach
import java.util.*;
  
class GFG
{
static int sz = (int) 1e5;
  
// Adjacency list representation
// of the tree
static Vector []tree = new Vector[sz + 1];
  
// Boolean array to mark all the
// vertices which are visited
static boolean []vis = new boolean[sz + 1];
  
// Array of vector where ith index
// stores the path from the root
// node to the ith node
static int []dis = new int[sz + 1];
  
static class pair
{ 
    int first, second; 
    public pair(int first, int second) 
    { 
        this.first = first; 
        this.second = second; 
    } 
}
  
// 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 qu = new LinkedList<>();
  
    // Push root node in the front of
    qu.add(new pair(node, 0 ));
    dis[0] = 0;
  
    while (!qu.isEmpty()) 
    {
        pair p = qu.peek();
  
        // Dequeue a vertex from queue
        qu.remove();
        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]) 
            {
                dis[child] = dis[p.first] + 1;
                qu.add(new pair(child, p.first));
            }
        }
    }
}
  
// Driver code
public static void main(String[] args)
{
      
    // Number of vertices
    int n = 6;
    for (int i = 0; i < sz + 1; i++) 
        tree[i] = new Vector();
          
    addEdge(0, 1);
    addEdge(0, 2);
    addEdge(1, 3);
    addEdge(2, 4);
    addEdge(2, 5);
  
    // Calling modified bfs function
    bfs(0);
  
    int q[] = { 2, 3 };
  
    for (int i = 0; i < 2; i++) 
    {
        System.out.println(dis[q[i]]);
    }
}
}
  
// This code is contributed by 29AjayKumar


Python3
# Python implementation for
# the above approach
  
from collections import deque
  
sz = int(1e5)
  
# Adjacency list representation
# of the tree
tree = [0] * (sz + 1)
for i in range(sz + 1):
    tree[i] = []
  
# Boolean array to mark all the
# vertices which are visited
vis = [False] * (sz + 1)
  
# Array of vector where ith index
# stores the path from the root
# node to the ith node
dis = [0] * sz
  
# Function to create an
# edge between two vertices
def addEdge(a: int, b: int):
    global tree
  
    # 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: int):
    global dis, vis
  
    # Create a queue of {child, parent}
    qu = deque()
  
    # Push root node in the front of
    qu.append((node, 0))
    dis[0] = 0
  
    while qu:
        p = qu[0]
  
        # Dequeue a vertex from queue
        qu.popleft()
        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 not vis[child]:
                dis[child] = dis[p[0]] + 1
                qu.append((child, p[0]))
  
# Driver Code
if __name__ == "__main__":
  
    # Number of vertices
    n = 6
  
    addEdge(0, 1)
    addEdge(0, 2)
    addEdge(1, 3)
    addEdge(2, 4)
    addEdge(2, 5)
  
    # Calling modified bfs function
    bfs(0)
  
    q = [2, 4]
  
    for i in range(2):
        print(dis[q[i]])
  
# This code is contributed by
# sanjeev2552


C#
// C# implementation for
// the above approach
using System;
using System.Collections.Generic;
      
class GFG
{
static int sz = (int) 1e5;
  
// Adjacency list representation
// of the tree
static List []tree = new List[sz + 1];
  
// Boolean array to mark all the
// vertices which are visited
static Boolean []vis = new Boolean[sz + 1];
  
// Array of vector where ith index
// stores the path from the root
// node to the ith node
static int []dis = new int[sz + 1];
  
public class pair
{ 
    public int first, second; 
    public pair(int first, int second) 
    { 
        this.first = first; 
        this.second = second; 
    } 
}
  
// 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 qu = new Queue();
  
    // Push root node in the front of
    qu.Enqueue(new pair(node, 0 ));
    dis[0] = 0;
  
    while (qu.Count != 0) 
    {
        pair p = qu.Peek();
  
        // Dequeue a vertex from queue
        qu.Dequeue();
        vis[p.first] = true;
  
        // Get all adjacent vertices of the dequeued
        // vertex s. If any adjacent has not
        // been visited then enqueue it
        foreach (int child in tree[p.first])
        {
            if (!vis[child]) 
            {
                dis[child] = dis[p.first] + 1;
                qu.Enqueue(new pair(child, p.first));
            }
        }
    }
}
  
// Driver code
public static void Main(String[] args)
{
      
    // Number of vertices
    for (int i = 0; i < sz + 1; i++) 
        tree[i] = new List();
          
    addEdge(0, 1);
    addEdge(0, 2);
    addEdge(1, 3);
    addEdge(2, 4);
    addEdge(2, 5);
  
    // Calling modified bfs function
    bfs(0);
  
    int []q = { 2, 3 };
  
    for (int i = 0; i < 2; i++) 
    {
        Console.WriteLine(dis[q[i]]);
    }
}
}
  
// This code is contributed by Rajput-Ji


输出:
1
2