Find if path length is even or odd between given Tree nodes for Q queries
Last Updated :
27 Dec, 2022
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
JavaScript
<script>
//JavaScript code for the above approach
// Stores the input tree
let adj = Array(100000).fill().map(() => []);
// Stores the set number of all nodes
let setNum = Array(100000).fill(-1);
// Function to add an edge in the tree
function addEdge(a1, a2) {
adj[a1].push(a2);
adj[a2].push(a1);
}
// Function to convert the given tree
// into a bipartite graph using BFS
function toBipartite(N) {
// Stores the current node during
// the BFS traversal of the tree
let 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.length > 0) {
// Current node
let v = q[0];
q.shift();
// Traverse over all neighbors
// of the current node
for (let u of 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
function pathLengthQuery(A, B) {
// If the set number of both nodes is
// same, path length is odd else even
if (setNum[A] === setNum[B]) {
document.write("Odd");
} else {
document.write("Even");
}
}
// Driver Code
let 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 Potta Lokesh
</script>
Time Complexity: O(N + Q)
Auxiliary Space: O(N)
Similar Reads
Find parents that are K level above given node for Q queries Given a tree with N nodes where node 1 is the root, the task is to solve the queries of form {u, k} and find the parent that is k level above the node u. Note: If the parent is not available then return -1. Examples: Input: N = 5 Q = 3, queries = {{4, 1}, {4, 2}, {4, 3}} Example of the tree Output:
10 min read
Find parent of each node in a tree for multiple queries Given a tree with N vertices numbered from 0 to N â 1 and Q query containing nodes in the tree, the task is to find the parent node of the given node for multiple queries. Consider the 0th node as the root node and take the parent of the root node as the root itself.Examples: Tree: 0 / \ 1 2 | / \ 3
8 min read
Count of nodes having odd divisors in the given subtree for Q queries Given a N-ary Tree and Q queries where each query contains a node of the N-ary tree, the task is to count the number of nodes that have an odd number of divisors in the subtree for Q queries. Examples: Input: Output: 1 3 0 1 Explanation: Query 1: In the subtree rooted at node 100, there is only one
8 min read
Count of paths in given Binary Tree with odd bitwise AND for Q queries Given an integer Q representing the number of queries and an array where each query has an integer N. Our task is to iterate through each query and find the number of paths such that bitwise AND of all nodes on that path is odd. A binary tree is constructed with N vertices numbered 1 through N. For
9 min read
Find the path from root to the given nodes of a tree for multiple queries Given a tree with N vertices numbered from 0 to N - 1 (0th node is the root node). Also, given q queries containing nodes in the tree. The task is to find the path from the root node to the given node for multiple queries. Examples: Input: N = 6, q[] = {2, 4} Tree: 0 / \ 1 2 | 3 / \ 4 5 Output: 0 2
10 min read