Skip to content
Related Articles

Related Articles

Find if path length is even or odd between given Tree nodes for Q queries

Improve Article
Save Article
  • Difficulty Level : Medium
  • Last Updated : 09 Nov, 2021
Improve Article
Save Article

Given a generic tree consisting of N nodes and (N – 1) edges and an array of queries query[] of size Q consisting of the type {A, B}, the task for each query is to check whether the path length between two given nodes A and B is even or odd.

Examples:

Input: query[] = {{2, 4}, {4, 0}}

Output:
Odd
Even
Explanation:
For the 1st query A = 2 and B = 4. The path from A to B is 2 -> 0 -> 1 -> 3 -> 4 having a length of 5 i.e., Odd.
For the 2nd query A = 4 and B = 0. The path from A to B is 4 -> 3 -> 1 -> 0 having a length of 4 i.e., Even.

Approach: The given problem can be efficiently solved by converting the tree into a Bipartite Graph. It can be observed that if the given nodes A and B in a query are on the same side in the constructed bipartite graph, then the path length between A and B must be odd and if A and B are on different sides, then the path length must be odd. Below are the steps to follow:

  • Traverse the given tree using the BFS Traversal.
  • Divide all nodes into 2 sets such that all the two adjacent nodes in the tree are in different sets (i.e., 0 or 1). In order to do so, assign an alternating set number to each level during the BFS traversal by assigning the set number of current nodes = 1 XOR the number of the parent of the current node.
  • After completing the above steps, traverse the given array of queries query[] and if the set number of both the nodes are the same, the path length of A to B is Odd. Otherwise, it is Even.

Below is the implementation of the above approach:

C++




// C++ program for the above approach
 
#include <bits/stdc++.h>
using namespace std;
 
// Stores the input tree
vector<vector<int> > adj(100000);
 
// Stores the set number of all nodes
vector<int> 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<int> 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<Integer> []adj = new Vector[100000];
 
// Stores the set number of all nodes
static Vector<Integer> setNum = new Vector<Integer>(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<Integer> 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<Integer>();
   
    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<int> []adj = new List<int>[100000];
 
// Stores the set number of all nodes
static List<int> setNum = new List<int>(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<int> q
            = new Queue<int>();
 
    // 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>();
   
    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

Output: 

Odd
Even

 

Time Complexity: O(N + Q)
Auxiliary Space: O(N)


My Personal Notes arrow_drop_up
Related Articles

Start Your Coding Journey Now!