📌  相关文章
📜  查找 Q 查询的给定树节点之间的路径长度是偶数还是奇数

📅  最后修改于: 2022-05-13 01:56:05.300000             🧑  作者: Mango

查找 Q 查询的给定树节点之间的路径长度是偶数还是奇数

给定一棵由N个节点和(N – 1)条边组成的通用树,以及一个大小为Q且类型为{A, B}的查询数组query[] ,每个查询的任务是检查两个查询之间的路径长度是否给定节点AB是偶数或奇数。

例子:

方法:给定的问题可以通过将树转换为二分图来有效地解决。可以看出,如果查询中的给定节点AB在构造的二分图中位于同一侧,则AB之间的路径长度一定是奇数,如果AB在不同侧,则路径长度必须是奇数。以下是要遵循的步骤:

  • 使用 BFS Traversal 遍历给定的树。
  • 将所有节点分成 2 个集合,使得树中的所有两个相邻节点都在不同的集合中(即01 )。为此,在 BFS 遍历期间,通过分配当前节点的集数 = 1 XOR 当前节点的父节点数,为每个级别分配一个交替集数。
  • 完成上述步骤后,遍历给定的查询数组query[] ,如果两个节点的集合数相同,则AB的路径长度为Odd 。否则,它是偶数

下面是上述方法的实现:

C++
// C++ program for the above approach
 
#include 
using namespace std;
 
// Stores the input tree
vector > adj(100000);
 
// Stores the set number of all nodes
vector setNum(100000);
 
// Function to add an edge in the tree
void addEdge(int a1, int a2)
{
    adj[a1].push_back(a2);
    adj[a2].push_back(a1);
}
 
// Function to convert the given tree
// into a bipartite graph using BFS
void toBipartite(int N)
{
    // Set the set number to -1 for
    // all node of the given tree
    setNum.assign(N, -1);
 
    // Stores the current node during
    // the BFS traversal of the tree
    queue q;
 
    // Initialize the set number of
    // 1st node and enqueue it
    q.push(0);
    setNum[0] = 0;
 
    // BFS traversal of the given tree
    while (!q.empty()) {
 
        // Current node
        int v = q.front();
        q.pop();
 
        // Traverse over all neighbours
        // of the current node
        for (int u : adj[v]) {
 
            // If the set is not assigned
            if (setNum[u] == -1) {
 
                // Assign set number to node u
                setNum[u] = setNum[v] ^ 1;
                q.push(u);
            }
        }
    }
}
 
// Function to find if the path length
// between node A and B is even or odd
void pathLengthQuery(int A, int B)
{
    // If the set number of both nodes is
    // same, path length is odd else even
    if (setNum[A] == setNum[B]) {
        cout << "Odd" << endl;
    }
    else {
        cout << "Even" << endl;
    }
}
 
// Driver Code
int main()
{
    int N = 7;
    addEdge(0, 1);
    addEdge(0, 2);
    addEdge(1, 3);
    addEdge(3, 4);
    addEdge(3, 5);
    addEdge(2, 6);
 
    // Function to convert tree into
    // bipartite
    toBipartite(N);
 
    pathLengthQuery(4, 2);
    pathLengthQuery(0, 4);
 
    return 0;
}


Java
// Java program for the above approach
 
import java.io.*;
import java.util.*;
 
class GFG {
   
// Stores the input tree
@SuppressWarnings("unchecked")
static Vector []adj = new Vector[100000];
 
// Stores the set number of all nodes
static Vector setNum = new Vector(100000);
 
// Function to add an edge in the tree
static void addEdge(int a1, int a2)
{
    adj[a1].add(a2);
    adj[a2].add(a1);
}
 
// Function to convert the given tree
// into a bipartite graph using BFS
static void toBipartite(int N)
{
    // Set the set number to -1 for
    // all node of the given tree
    for (int i = 0; i < 100000; i++)
       setNum.add(-1);
 
    // Stores the current node during
    // the BFS traversal of the tree
    Queue q
            = new LinkedList<>();
 
    // Initialize the set number of
    // 1st node and enqueue it
    q.add(0);
    setNum.set(0, 0);
 
    // BFS traversal of the given tree
    while (!q.isEmpty()) {
 
        // Current node
        int v = q.peek();
        q.remove();
 
        // Traverse over all neighbours
        // of the current node
        for (int u : adj[v]) {
 
            // If the set is not assigned
            if (setNum.get(u) == -1) {
 
                // Assign set number to node u
                  setNum.set(u, setNum.get(v) ^ 1);
                q.add(u);
            }
        }
    }
}
 
// Function to find if the path length
// between node A and B is even or odd
static void pathLengthQuery(int A, int B)
{
    // If the set number of both nodes is
    // same, path length is odd else even
    if (setNum.get(A) == setNum.get(B)) {
        System.out.println("Odd");
    }
    else {
        System.out.println("Even");
    }
}
 
// Driver Code
public static void main (String[] args) {
       
      for (int i = 0; i < 100000; i++)
       adj[i] = new Vector();
   
    int N = 7;
    addEdge(0, 1);
    addEdge(0, 2);
    addEdge(1, 3);
    addEdge(3, 4);
    addEdge(3, 5);
    addEdge(2, 6);
 
    // Function to convert tree into
    // bipartite
    toBipartite(N);
 
    pathLengthQuery(4, 2);
    pathLengthQuery(0, 4);
}
}
 
// This code is contributed by Dharanendra L V.


Python3
# Python program for the above approach
from queue import Queue
 
# Stores the input tree
adj = [[0] * 100000] * 100000
 
# Stores the set number of all nodes
setNum = [0] * 100000
 
# Function to add an edge in the tree
def addEdge(a1, a2):
    adj[a1].append(a2);
    adj[a2].append(a1);
 
 
# Function to convert the given tree
# into a bipartite graph using BFS
def toBipartite(N):
   
    # Set the set number to -1 for
    # all node of the given tree
    for i in range(0, N):
        setNum[i] = -1
 
    # Stores the current node during
    # the BFS traversal of the tree
    q = Queue();
 
    # Initialize the set number of
    # 1st node and enqueue it
    q.put(0);
    setNum[0] = 0;
 
    # BFS traversal of the given tree
    while (not q.empty()):
 
        # Current node
        v = q.queue[0];
        q.get();
 
        # Traverse over all neighbours
        # of the current node
        for u in adj[v]:
 
            # If the set is not assigned
            if (setNum[u] == -1):
 
                # Assign set number to node u
                setNum[u] = setNum[v] ^ 1;
                q.put(u);
             
 
# Function to find if the path length
# between node A and B is even or odd
def pathLengthQuery(A, B):
    # If the set number of both nodes is
    # same, path length is odd else even
    if (setNum[A] == setNum[B]):
        print("Odd");
    else:
        print("Even");
 
# Driver Code
N = 7;
addEdge(0, 1);
addEdge(0, 2);
addEdge(1, 3);
addEdge(3, 4);
addEdge(3, 5);
addEdge(2, 6);
 
    # Function to convert tree into
    # bipartite
toBipartite(N);
 
pathLengthQuery(4, 2);
pathLengthQuery(0, 4);
 
# This code is contributed by _saurabh_jaiswal.


C#
// C# program for the above approach
using System;
using System.Collections.Generic;
 
public class GFG
{
   
// Stores the input tree
static List []adj = new List[100000];
 
// Stores the set number of all nodes
static List setNum = new List(100000);
 
// Function to add an edge in the tree
static void addEdge(int a1, int a2)
{
    adj[a1].Add(a2);
    adj[a2].Add(a1);
}
 
// Function to convert the given tree
// into a bipartite graph using BFS
static void toBipartite(int N)
{
   
    // Set the set number to -1 for
    // all node of the given tree
    for (int i = 0; i < 100000; i++)
       setNum.Add(-1);
 
    // Stores the current node during
    // the BFS traversal of the tree
    Queue q
            = new Queue();
 
    // Initialize the set number of
    // 1st node and enqueue it
    q.Enqueue(0);
    setNum[0] =  0;
 
    // BFS traversal of the given tree
    while (q.Count!=0) {
 
        // Current node
        int v = q.Peek();
        q.Dequeue();
 
        // Traverse over all neighbours
        // of the current node
        foreach (int u in adj[v]) {
 
            // If the set is not assigned
            if (setNum[u] == -1) {
 
                // Assign set number to node u
                  setNum[u] = ( setNum[v] ^ 1);
                q.Enqueue(u);
            }
        }
    }
}
 
// Function to find if the path length
// between node A and B is even or odd
static void pathLengthQuery(int A, int B)
{
   
    // If the set number of both nodes is
    // same, path length is odd else even
    if (setNum[A] == setNum[B])
    {
        Console.WriteLine("Odd");
    }
    else
    {
        Console.WriteLine("Even");
    }
}
 
// Driver Code
public static void Main(String[] args) {
       
      for (int i = 0; i < 100000; i++)
       adj[i] = new List();
   
    int N = 7;
    addEdge(0, 1);
    addEdge(0, 2);
    addEdge(1, 3);
    addEdge(3, 4);
    addEdge(3, 5);
    addEdge(2, 6);
 
    // Function to convert tree into
    // bipartite
    toBipartite(N);
 
    pathLengthQuery(4, 2);
    pathLengthQuery(0, 4);
}
}
 
// This code is contributed by shikhasingrajput


输出:
Odd
Even

时间复杂度: O(N + Q)
辅助空间: O(N)