Open In App

Count pairs of vertices in Tree such that distance between them is even

Last Updated : 15 Feb, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Given a tree of N vertices, the task is to find the number of pairs of vertices such that the distance between them is even but cannot be 0

Examples:

Input: N = 5, Edges = [ [1, 0], [2, 1], [3, 1], [4, 3] ]

                        0
                     /          
                  1           
               /    \ 
            2        3
                        \
                         4 

Output: 4
Explanation: There are four pairs of vertices such that the distance between them is even.
They are [ 0, 2 ], [0, 3], [3, 2] and [1, 4].

Input: N = 6, Edges: [[1, 0], [2, 1], [3, 1], [4, 2], [5, 3]]

                           0
                        /         
                     1            
               /       \
           2            3
        /             /
     4              5
Output: 6
Explanation: There are 6 pairs of vertices such that the distance between them is even. They are [0, 2], [4, 1], [3, 0], [4, 5], [1, 5] and [2, 3].

 

Naive Approach: The naive approach is to try all possible pairs of vertices, find the distance between them and check if the distance is even. Follow the steps mentioned below to solve the problem:

  • Iterate over all the vertices for i = 0 to N-1:
    • Iterate from j = i+1 to N-1:
      • Find the distance from i to j using DFS.
      • If the distance is even then increment the count of pairs.
  • Return the count.

Below is the implementation of the above approach.

C++




// C++ code to implement the approach
 
#include <bits/stdc++.h>
using namespace std;
 
// Function to find the distance
void dfs(int i, int par,
         vector<vector<int> >& adj,
         vector<int>& dis)
{
    // Iterate over all the edges of vertex i
    for (int j : adj[i]) {
 
        // If 'j' is not the parent of 'i'.
        if (j != par) {
 
            // Store the distance
            // from root till 'j'.
            dis[j] = dis[i] + 1;
 
            // Recurse for the child 'j'.
            dfs(j, i, adj, dis);
        }
    }
}
 
// Function to count pairs
int countPairs(int n,
               vector<vector<int> >& edges)
{
    // Stores the final answer.
    int ans = 0;
 
    // Stores the adjacency List of the tree.
    vector<vector<int> > adj(n);
 
    for (int i = 0; i < n - 1; ++i) {
 
        // Add the edge in the adjacency list.
        adj[edges[i][0]].push_back(edges[i][1]);
        adj[edges[i][1]].push_back(edges[i][0]);
    }
 
    // Stores the distance from root till 'i'.
    vector<int> dis(n);
 
    // Iterate over all 'u'
    // of the pair ('u', 'v').
    for (int i = 0; i < n; ++i) {
 
        // Set all the values
        // of 'dis[i]' to '0'.
        fill(dis.begin(), dis.end(), 0);
 
        // Do a dfs with 'i' as
        // the root of the tree.
        dfs(i, -1, adj, dis);
 
        // Iterate over the other end
        // of the pair.
        for (int j = i + 1; j < n; ++j) {
 
            // If the distance is even.
            if (dis[j] % 2 == 0) {
 
                // Increment 'ans' by 1.
                ans++;
            }
        }
    }
 
    // Return the answer 'ans'.
    return ans;
}
 
// Driver Code
int main()
{
    int N = 5;
    vector<vector<int> > edges
        = { { 1, 0 }, { 2, 1 }, { 3, 1 }, { 4, 3 } };
 
    // Function call
    cout << countPairs(N, edges);
    return 0;
}


Java




// Java code to implement above approach
import java.util.*;
 
public class Main
{
 
  // Function to find the distance
  static void dfs(int i, int par,
                  ArrayList <ArrayList<Integer> > adj,
                  ArrayList <Integer> dis)
  {
    // Iterate over all the edges of vertex i
    for (int j : adj.get(i) ) {
 
      // If 'j' is not the parent of 'i'.
      if (j != par) {
 
        // Store the distance
        // from root till 'j'.
        dis.set(j, dis.get(i) + 1);
 
        // Recurse for the child 'j'.
        dfs(j, i, adj, dis);
      }
    }
  }
 
  // Function to count pairs
  static int countPairs(int n,
                        int[][] edges)
  {
    // Stores the final answer.
    int ans = 0;
 
    // Stores the adjacency List of the tree.
    ArrayList <ArrayList<Integer> > adj =
      new ArrayList<ArrayList<Integer> >(n);
    for (int i = 0; i < n; i++)
      adj.add(new ArrayList<Integer>());
 
    for (int i = 0; i < n - 1; ++i) {
 
      // Add the edge in the adjacency list.
      adj.get(edges[i][0]).add(edges[i][1]);
      adj.get(edges[i][1]).add(edges[i][0]);
    }
 
    // Iterate over all 'u'
    // of the pair ('u', 'v').
    for (int i = 0; i < n; ++i) {
 
      ArrayList <Integer> dis =
        new ArrayList<Integer> (n);;
      // Do a dfs with 'i' as
      // the root of the tree.
      for (int j = 0; j < n; ++j) {
        dis.add(0);
      }
      dfs(i, -1, adj, dis);
 
      // Iterate over the other end
      // of the pair.
      for (int j = i + 1; j < n; ++j) {
 
        // If the distance is even.
        if (dis.get(j) % 2 == 0) {
 
          // Increment 'ans' by 1.
          ans++;
        }
      }
    }
 
    // Return the answer 'ans'.
    return ans;
  }
  // Driver Code
  public static void main(String args[])
  {
    int N = 5;
 
    // array of edges
    int[][] edges
      = { { 1, 0 }, { 2, 1 }, { 3, 1 }, { 4, 3 } };
 
    // Function call
    System.out.println( countPairs(N, edges) );
 
  }
}
 
// This code is contributed by Sachin Sahara (sachin801)


Python3




# Python3 code to implement the approach
from typing import List, Tuple
 
# Function to find the distance
def dfs(i: int, par: int, adj: List[List[int]], dis: List[int]):
   
    # Iterate over all the edges of vertex i
    for j in adj[i]:
       
        # If 'j' is not the parent of 'i'.
        if j != par:
           
            # Store the distance
            # from root till 'j'.
            dis[j] = dis[i] + 1
             
            # Recurse for the child 'j'.
            dfs(j, i, adj, dis)
 
# Function to count pairs
def countPairs(n: int, edges: List[Tuple[int, int]]) -> int:
   
    # Stores the final answer.
    ans = 0
 
    # Stores the adjacency List of the tree.
    adj = [[] for i in range(n)]
 
    for i in range(n - 1):
        # Add the edge in the adjacency list.
        adj[edges[i][0]].append(edges[i][1])
        adj[edges[i][1]].append(edges[i][0])
 
    # Stores the distance from root till 'i'.
    dis = [0] * n
 
    # Iterate over all 'u'
    # of the pair ('u', 'v').
    for i in range(n):
       
        # Set all the values
        # of 'dis[i]' to '0'.
        dis = [0] * n
         
        # Do a dfs with 'i' as
        # the root of the tree.
        dfs(i, -1, adj, dis)
 
        # Iterate over the other end
        # of the pair.
        for j in range(i + 1, n):
           
            # If the distance is even.
            if dis[j] % 2 == 0:
               
                # Increment 'ans' by 1.
                ans += 1
 
    # Return the answer 'ans'.
    return ans
 
# Driver Code
if __name__ == "__main__":
    N = 5
    edges = [(1, 0), (2, 1), (3, 1), (4, 3)]
 
    # Function call
    print(countPairs(N, edges))
     
# This code is contributed by Potta Lokesh


C#




// C# code to implement the approach
using System;
using System.Collections.Generic;
 
public class GFG {
 
  // Function to find the distance
  static void dfs(int i, int par, List<List<int> > adj,
                  List<int> dis)
  {
 
    // Iterate over all the edges of vertex i
    foreach(int j in adj[i])
    {
 
      // If 'j' is not the parent of 'i'.
      if (j != par)
      {
 
        // Store the distance from root till 'j'.
        dis[j] = dis[i] + 1;
 
        // Recurse for the child 'j'.
        dfs(j, i, adj, dis);
      }
    }
  }
 
  // Function to count pairs
  static int countPairs(int n, int[, ] edges)
  {
 
    // Stores the final answer
    int ans = 0;
 
    // Stores the adjacency List of the tree.
    List<List<int> > adj = new List<List<int> >(n);
 
    for (int i = 0; i < n; i++) {
      adj.Add(new List<int>());
    }
 
    for (int i = 0; i < n - 1; ++i)
    {
 
      // Add the edge in the adjacency list.
      adj[edges[i, 0]].Add(edges[i, 1]);
      adj[edges[i, 1]].Add(edges[i, 0]);
    }
 
    // Iterate over all 'u'
    // of the pair ('u', 'v')
    for (int i = 0; i < n; ++i) {
      List<int> dis = new List<int>(n);
 
      // Do a dfs with 'i' as the root of the tree.
      for (int j = 0; j < n; ++j) {
        dis.Add(0);
      }
      dfs(i, -1, adj, dis);
 
      // Iterate over the other end of the pair
      for (int j = i + 1; j < n; ++j)
      {
 
        // If the distance is even
        if (dis[j] % 2 == 0)
        {
 
          // Increment 'ans' by 1.
          ans++;
        }
      }
    }
 
    // Return the answer 'ans'.
    return ans;
  }
 
  static public void Main()
  {
 
    // Code
    int N = 5;
 
    // array of edges
    int[, ] edges
      = { { 1, 0 }, { 2, 1 }, { 3, 1 }, { 4, 3 } };
 
    // Function call
    Console.WriteLine(countPairs(N, edges));
  }
}
 
// This code is contributed by lokeshmvs21.


Javascript




<script>
 
// JavaScript code to implement the approach
 
// Function to find the distance
function dfs(i, par, adj, dis)
{
    // Iterate over all the edges of vertex i
    for (let j of adj[i]) {
 
        // If 'j' is not the parent of 'i'.
        if (j != par) {
 
            // Store the distance
            // from root till 'j'.
            dis[j] = dis[i] + 1;
 
            // Recurse for the child 'j'.
            dfs(j, i, adj, dis);
        }
    }
}
 
// Function to count pairs
function countPairs(n,edges)
{
    // Stores the final answer.
    let ans = 0;
 
    // Stores the adjacency List of the tree.
    let adj = new Array(n);
    for(let i=0;i<N;i++){
        adj[i] = new Array();
    }
 
    for (let i = 0; i < n - 1; ++i) {
        
        // Add the edge in the adjacency list.
        adj[edges[i][0]].push(edges[i][1]);
        adj[edges[i][1]].push(edges[i][0]);
    }
 
    // Stores the distance from root till 'i'.
    let dis = new Array(n);;
 
    // Iterate over all 'u'
    // of the pair ('u', 'v').
    for (let i = 0; i < n; ++i) {
 
        // Set all the values
        // of 'dis[i]' to '0'.
        dis.fill(0);
 
        // Do a dfs with 'i' as
        // the root of the tree.
        dfs(i, -1, adj, dis);
 
        // Iterate over the other end
        // of the pair.
        for (let j = i + 1; j < n; ++j) {
 
            // If the distance is even.
            if (dis[j] % 2 == 0) {
 
                // Increment 'ans' by 1.
                ans++;
            }
        }
    }
 
    // Return the answer 'ans'.
    return ans;
}
 
// Driver Code
 
let N = 5;
let edges = [ [ 1, 0 ], [ 2, 1 ], [ 3, 1 ], [ 4, 3 ] ];
 
// Function call
document.write(countPairs(N, edges));
 
// This code is contributed by shinjanpatra
 
</script>


Output

4

Time Complexity: O(N2)
Auxiliary Space: O(N)

Efficient Approach: The efficient approach to solve the problem is based on the concept of bipartite graph as shown below.

Every tree is a bipartite graph. So all the vertices are part of one of the two bipartite sets (say L and R). 
Any pair having both the values from different sets have an odd distance between them and pairs with vertices from the same set have even distance between them.

Based on the above observation it is clear that the total number of pairs is the possible pairs formed using vertices from the same set i.e., (xC2) + (yC2), where [ nC2 = n * (n – 1)/2, x is the size of set L and y is the size of set R ]. Follow the steps mentioned below to solve the problem.

  • Declare and initialize two variables x and y to 0 to store the size of the bipartite sets.
  • Make root a part of one of the bipartite set (say L).
  • Start a DFS or BFS from the vertex 0 and in the recursion keep track of its distance from the root:
    • At each instant, iterate through all the children, and if we have not visited this child yet (let’s say the child is j), then:
      • Increment the distance of the parent node to get the distance of the child.
      • If it is even, increment x and make it part of set L. Otherwise, increment y and make it part of set R.
    • Recursively do the same for its children.
  • Finally, return the value of xC2 + yC2.

Below is the implementation of the above approach.

C++




// C++ code to implement the approach
 
#include <bits/stdc++.h>
using namespace std;
 
// To store the size of set 'L'
// size of set 'R'.
int x = 0, y = 0;
 
// Dfs function
void dfs(int i, int par, vector<vector<int> >& adj, int dis)
{
    // Iterate over all edges of vertex 'i'.
    if (dis % 2 == 0)
        x++;
    else
        y++;
    for (int j : adj[i]) {
 
        // If 'j' is not the parent of 'i'.
        if (j != par) {
 
            // Recurse for the child 'j'.
            dfs(j, i, adj, dis+1);
        }
    }
}
 
// Function to count the vertices
int countPairs(int n, vector<vector<int> >& edges)
{
    // Stores the adjacency List of the tree.
    vector<vector<int> > adj(n);
    for (int i = 0; i < n - 1; ++i) {
 
        // Add the edge in the adjacency list.
        adj[edges[i][0]].push_back(edges[i][1]);
        adj[edges[i][1]].push_back(edges[i][0]);
    }
 
    // Dfs with '0' as the root of the tree.
    dfs(0, -1, adj, 0);
 
    // Return the answer.
    return x * (x - 1) / 2 + y * (y - 1) / 2;
}
 
// Driver Code
int main()
{
    int N = 5;
    vector<vector<int> > edges
        = { { 1, 0 }, { 2, 1 }, { 3, 1 }, { 4, 3 } };
 
    // Function call
    cout << countPairs(N, edges);
    return 0;
}


Java




// Java code to implement above approach
 
import java.util.*;
 
public class Main {
 
    // To store the size of set 'L'
    // size of set 'R'.
    static int x = 0, y = 0;
 
    // Function to find the distance
    static void dfs(int i, int par,
                    ArrayList<ArrayList<Integer> > adj,
                    int dis)
    {
        if (dis % 2 == 0)
            x++;
        else
            y++;
 
        // Iterate over all the edges of vertex i
        for (int j : adj.get(i)) {
 
            // If 'j' is not the parent of 'i'.
            if (j != par) {
 
                // Recurse for the child 'j'.
                dfs(j, i, adj, dis + 1);
            }
        }
    }
 
    // Function to count pairs
    static int countPairs(int n, int[][] edges)
    {
        // Stores the adjacency List of the tree.
        ArrayList<ArrayList<Integer> > adj
            = new ArrayList<ArrayList<Integer> >(n);
        for (int i = 0; i < n; i++)
            adj.add(new ArrayList<Integer>());
 
        for (int i = 0; i < n - 1; ++i) {
 
            // Add the edge in the adjacency list.
            adj.get(edges[i][0]).add(edges[i][1]);
            adj.get(edges[i][1]).add(edges[i][0]);
        }
 
        // Dfs with '0' as the root of the tree.
        dfs(0, -1, adj, 0);
 
        // Return the answer.
        return x * (x - 1) / 2 + y * (y - 1) / 2;
    }
 
    // Driver Code
    public static void main(String args[])
    {
        int N = 5;
        // array of edges
        int[][] edges
            = { { 1, 0 }, { 2, 1 }, { 3, 1 }, { 4, 3 } };
 
        // Function call
        System.out.println(countPairs(N, edges));
    }
}
 
// This code is contributed by Sachin Sahara (sachin801)


Python3




# python3 code to implement the approach
 
# To store the size of set 'L'
# size of set 'R'.
x, y = 0, 0
 
# Dfs function
def dfs(i, par, adj, dis):
 
    global x
    global y
    if dis % 2 == 0:
        x += 1
    else:
        y += 1
         
    # Iterate over all edges of vertex 'i'.
    for j in adj[i]:
 
        # If 'j' is not the parent of 'i'.
        if (j != par):
 
            # Recurse for the child 'j'.
            dfs(j, i, adj, dis+1)
 
# Function to count the vertices
def countPairs(n, edges):
 
    # Stores the adjacency List of the tree.
    adj = [[] for _ in range(n)]
    for i in range(0, n-1):
 
        # Add the edge in the adjacency list.
        adj[edges[i][0]].append(edges[i][1])
        adj[edges[i][1]].append(edges[i][0])
         
 
    # Dfs with '0' as the root of the tree.
    dfs(0, -1, adj, 0)
 
    # Return the answer.
    return x * (x - 1) // 2 + y * (y - 1) // 2
 
 
# Driver Code
if __name__ == "__main__":
 
    N = 5
    edges = [[1, 0], [2, 1], [3, 1], [4, 3]]
 
    # Function call
    print(countPairs(N, edges))
 
# This code is contributed by rakeshsahni


C#




using System;
using System.Collections;
using System.Collections.Generic;
 
// // C# program to print all Alpha-Numeric Abbreviations
// // of a String
class GFG {
 
  public static int x = 0;
  public static int y = 0;
 
  // Dfs function
  public static void dfs(int i, int par, LinkedList<int>[] adj, int dis)
  {
     
    // Iterate over all edges of vertex 'i'.
    if (dis % 2 == 0)
      x++;
    else
      y++;
 
    foreach(var j in adj[i])
    {
      if(j != par){
        dfs(j, i, adj, dis + 1);
      }
    }
  }
 
  // Function to count the vertices
  public static int countPairs(int n, int[,] edges)
  {
     
    // Stores the adjacency List of the tree.
    LinkedList<int>[] adj = new LinkedList<int>[n];
    for (int i = 0; i < n; i++)
      adj[i] = new LinkedList<int>();
 
    for (int i = 0; i < n - 1; ++i) {
 
      // Add the edge in the adjacency list.
      adj[edges[i,0]].AddLast(edges[i,1]);
      adj[edges[i,1]].AddLast(edges[i,0]);
    }
 
    // Dfs with '0' as the root of the tree.
    dfs(0, -1, adj, 0);
 
    // Return the answer.
    return x * (x - 1) / 2 + y * (y - 1) / 2;
  }
 
  static void Main() {
 
    int N = 5;
    int[,] edges = { { 1, 0 }, { 2, 1 }, { 3, 1 }, { 4, 3 } };
 
    // Function call
    Console.WriteLine(countPairs(N, edges));
  }
}
 
// The code is contributed by Nidhi goel.


Javascript




// to store the size of set 'L' and 'R'
let x = 0, y = 0;
 
// function to find the distance
function dfs(i, par, adj, dis)
{
 
  // increment x if dis is even
  if (dis % 2 === 0) {
    x++;
  } else { // increment y if dis is odd
    y++;
  }
   
  // iterate over all the edges of vertex i
  adj[i].forEach(j => {
   
    // if 'j' is not the parent of 'i'
    if (j !== par)
    {
     
      // recurse for the child 'j'
      dfs(j, i, adj, dis + 1);
    }
  });
}
 
// function to count pairs
function countPairs(n, edges)
{
 
  // stores the adjacency list of the tree
  const adj = [];
  for (let i = 0; i < n; i++) {
    adj[i] = [];
  }
 
  // add the edges in the adjacency list
  for (let i = 0; i < n - 1; i++) {
    adj[edges[i][0]].push(edges[i][1]);
    adj[edges[i][1]].push(edges[i][0]);
  }
 
  // dfs with '0' as the root of the tree
  dfs(0, -1, adj, 0);
 
  // return the answer
  return x * (x - 1) / 2 + y * (y - 1) / 2;
}
 
// driver code
const N = 5;
// array of edges
const edges = [[1, 0], [2, 1], [3, 1], [4, 3]];
 
// function call
console.log(countPairs(N, edges));
 
 
// This code is contributed by Edula Vinay Kumar Reddy


Output

4

Time Complexity: O(N)
Auxiliary Space: O(1) If the space for recursion call stack is considered then it is O(h) where h is the height of tree



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads