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++
#include <bits/stdc++.h>
using namespace std;
vector<vector< int > > adj(100000);
vector< int > setNum(100000);
void addEdge( int a1, int a2)
{
adj[a1].push_back(a2);
adj[a2].push_back(a1);
}
void toBipartite( int N)
{
setNum.assign(N, -1);
queue< int > q;
q.push(0);
setNum[0] = 0;
while (!q.empty()) {
int v = q.front();
q.pop();
for ( int u : adj[v]) {
if (setNum[u] == -1) {
setNum[u] = setNum[v] ^ 1;
q.push(u);
}
}
}
}
void pathLengthQuery( int A, int B)
{
if (setNum[A] == setNum[B]) {
cout << "Odd" << endl;
}
else {
cout << "Even" << endl;
}
}
int main()
{
int N = 7;
addEdge(0, 1);
addEdge(0, 2);
addEdge(1, 3);
addEdge(3, 4);
addEdge(3, 5);
addEdge(2, 6);
toBipartite(N);
pathLengthQuery(4, 2);
pathLengthQuery(0, 4);
return 0;
}
|
Java
import java.io.*;
import java.util.*;
class GFG {
@SuppressWarnings ( "unchecked" )
static Vector<Integer> []adj = new Vector[ 100000 ];
static Vector<Integer> setNum = new Vector<Integer>( 100000 );
static void addEdge( int a1, int a2)
{
adj[a1].add(a2);
adj[a2].add(a1);
}
static void toBipartite( int N)
{
for ( int i = 0 ; i < 100000 ; i++)
setNum.add(- 1 );
Queue<Integer> q
= new LinkedList<>();
q.add( 0 );
setNum.set( 0 , 0 );
while (!q.isEmpty()) {
int v = q.peek();
q.remove();
for ( int u : adj[v]) {
if (setNum.get(u) == - 1 ) {
setNum.set(u, setNum.get(v) ^ 1 );
q.add(u);
}
}
}
}
static void pathLengthQuery( int A, int B)
{
if (setNum.get(A) == setNum.get(B)) {
System.out.println( "Odd" );
}
else {
System.out.println( "Even" );
}
}
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 );
toBipartite(N);
pathLengthQuery( 4 , 2 );
pathLengthQuery( 0 , 4 );
}
}
|
Python3
from queue import Queue
adj = [[ 0 ] * 100000 ] * 100000
setNum = [ 0 ] * 100000
def addEdge(a1, a2):
adj[a1].append(a2);
adj[a2].append(a1);
def toBipartite(N):
for i in range ( 0 , N):
setNum[i] = - 1
q = Queue();
q.put( 0 );
setNum[ 0 ] = 0 ;
while ( not q.empty()):
v = q.queue[ 0 ];
q.get();
for u in adj[v]:
if (setNum[u] = = - 1 ):
setNum[u] = setNum[v] ^ 1 ;
q.put(u);
def pathLengthQuery(A, B):
if (setNum[A] = = setNum[B]):
print ( "Odd" );
else :
print ( "Even" );
N = 7 ;
addEdge( 0 , 1 );
addEdge( 0 , 2 );
addEdge( 1 , 3 );
addEdge( 3 , 4 );
addEdge( 3 , 5 );
addEdge( 2 , 6 );
toBipartite(N);
pathLengthQuery( 4 , 2 );
pathLengthQuery( 0 , 4 );
|
C#
using System;
using System.Collections.Generic;
public class GFG
{
static List< int > []adj = new List< int >[100000];
static List< int > setNum = new List< int >(100000);
static void addEdge( int a1, int a2)
{
adj[a1].Add(a2);
adj[a2].Add(a1);
}
static void toBipartite( int N)
{
for ( int i = 0; i < 100000; i++)
setNum.Add(-1);
Queue< int > q
= new Queue< int >();
q.Enqueue(0);
setNum[0] = 0;
while (q.Count!=0) {
int v = q.Peek();
q.Dequeue();
foreach ( int u in adj[v]) {
if (setNum[u] == -1) {
setNum[u] = ( setNum[v] ^ 1);
q.Enqueue(u);
}
}
}
}
static void pathLengthQuery( int A, int B)
{
if (setNum[A] == setNum[B])
{
Console.WriteLine( "Odd" );
}
else
{
Console.WriteLine( "Even" );
}
}
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);
toBipartite(N);
pathLengthQuery(4, 2);
pathLengthQuery(0, 4);
}
}
|
Javascript
<script>
let adj = Array(100000).fill().map(() => []);
let setNum = Array(100000).fill(-1);
function addEdge(a1, a2) {
adj[a1].push(a2);
adj[a2].push(a1);
}
function toBipartite(N) {
let q = [];
q.push(0);
setNum[0] = 0;
while (q.length > 0) {
let v = q[0];
q.shift();
for (let u of adj[v]) {
if (setNum[u] === -1) {
setNum[u] = setNum[v] ^ 1;
q.push(u);
}
}
}
}
function pathLengthQuery(A, B) {
if (setNum[A] === setNum[B]) {
document.write( "Odd" );
} else {
document.write( "Even" );
}
}
let N = 7;
addEdge(0, 1);
addEdge(0, 2);
addEdge(1, 3);
addEdge(3, 4);
addEdge(3, 5);
addEdge(2, 6);
toBipartite(N);
pathLengthQuery(4, 2);
pathLengthQuery(0, 4);
</script>
|
Time Complexity: O(N + Q)
Auxiliary Space: O(N)
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...