查找 Q 查询的给定树节点之间的路径长度是偶数还是奇数
给定一棵由N个节点和(N – 1)条边组成的通用树,以及一个大小为Q且类型为{A, B}的查询数组query[] ,每个查询的任务是检查两个查询之间的路径长度是否给定节点A和B是偶数或奇数。
例子:
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.
方法:给定的问题可以通过将树转换为二分图来有效地解决。可以看出,如果查询中的给定节点A和B在构造的二分图中位于同一侧,则A和B之间的路径长度一定是奇数,如果A和B在不同侧,则路径长度必须是奇数。以下是要遵循的步骤:
- 使用 BFS Traversal 遍历给定的树。
- 将所有节点分成 2 个集合,使得树中的所有两个相邻节点都在不同的集合中(即0或1 )。为此,在 BFS 遍历期间,通过分配当前节点的集数 = 1 XOR 当前节点的父节点数,为每个级别分配一个交替集数。
- 完成上述步骤后,遍历给定的查询数组query[] ,如果两个节点的集合数相同,则A到B的路径长度为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)