Open In App

Count ways to choose Triplets of Pairs such that either first or second values are distinct

Last Updated : 23 Jan, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Given an array of pairs arr[] of size N (N ? 3) where each element of pair is at most N and each pair is unique, the task is to determine the number of ways to select triplets from the given N pairs that satisfy at least one of the following conditions:

  • The first value (a) of each pair should be distinct.
  • The second value (b) of each pair should be distinct.

Examples:

Input: N = 4, arr[] = {{2, 4}, {3, 4}, {2, 1}, {1, 4}} 
Output: 2
Explanation: The valid triplets are {{2, 4}. {3, 4}, {1, 4}} 
and {{3, 4}, {2, 1}, {1, 4}}

Input: N = 5, arr[] = {{1, 4}, {2, 4}, {3, 3}, {4, 2}, {1, 2}}
Output: 8

Approach: Use the below idea to solve the problem

The total number of triplets possible is n*(n – 1)*(n – 2)/6. So we can count the number of invalid pairs for the triplets and subtract that count from the total triplets possible

Follow the below steps to solve the problem:

  • Create two 2D vectors to keep a record of the pairs in the given array.
  • Store pairs with the same first value in the first 2D vector and pairs with the same second value in the second 2D vector.
  • Initialize ans = N*(N – 1)*(N – 2)/6, the count of total pairs possible.
  • Traverse over first 2D vector and calculate the number of triplets that are not possible with each value in the given array.
  • Subtract the count of invalid pairs from the ans.
  • Return ans as the final answer.

Below is the implementation of the ab

C++




// C++ code for the above approach
 
#include <bits/stdc++.h>
using namespace std;
 
void solve(vector<vector<int> >& details, int N)
{
 
    // Vector to store the pairs with
    // common values
    vector<int> adj_a[N + 1], adj_b[N + 1];
 
    for (int i = 0; i < N; i++) {
 
        // Storing pairs with same first values
        adj_a[details[i][0]].push_back(details[i][1]);
 
        // Storing pairs with same second values
        adj_b[details[i][1]].push_back(details[i][0]);
    }
 
    // Total ways to choose a triplet from
    // n pairs is nc3
    int ans = (N * (N - 1) * (N - 2)) / 6;
 
    for (int i = 1; i < N + 1; i++) {
 
        // Size to keep record of the elements
        // with same first values
        int size = adj_a[i].size();
 
        for (auto& u : adj_a[i]) {
 
            // Count of pairs that forms
            // invalid triplets
            int same_cnt = adj_b[u].size() - 1;
 
            // Subtracting the invalid values
            ans -= (size - 1) * same_cnt;
        }
    }
    // Printing the answer
    cout << ans << endl;
}
 
// Driver's code
int main()
{
 
    // Given input
    int n = 5;
    vector<vector<int> > details{
        { 1, 4 }, { 2, 4 }, { 3, 3 }, { 4, 2 }, { 1, 2 }
    };
 
    // Function Call
    solve(details, n);
 
    return 0;
}


Java




// Java code for the above approach
import java.io.*;
import java.util.*;
 
class GFG {
    @SuppressWarnings("unchecked")
    public static void solve(int details[][], int N)
    {
        // ArrayList to store the pairs with
        // common values
        ArrayList<Integer>[] adj_a = new ArrayList[N + 1];
        ArrayList<Integer>[] adj_b = new ArrayList[N + 1];
        for (int i = 0; i < N + 1; i++) {
            adj_a[i] = new ArrayList<Integer>();
            adj_b[i] = new ArrayList<Integer>();
        }
        // ArrayList<ArrayList<Integer>> adj_a=new
        // ArrayList<ArrayList<Integer>>(N+1);
        // ArrayList<ArrayList<Integer>> adj_b=new
        // ArrayList<ArrayList<Integer>>(N+1);
 
        for (int i = 0; i < N; i++) {
 
            // Storing pairs with same first values
            adj_a[details[i][0]].add(details[i][1]);
 
            // Storing pairs with same second values
            adj_b[details[i][1]].add(details[i][0]);
        }
 
        // Total ways to choose a triplet from
        // n pairs is nc3
        int ans = (N * (N - 1) * (N - 2)) / 6;
 
        for (int i = 1; i < N + 1; i++) {
 
            // Size to keep record of the elements
            // with same first values
            int size = adj_a[i].size();
 
            for (Integer u : adj_a[i]) {
 
                // Count of pairs that forms
                // invalid triplets
                int same_cnt = adj_b[u].size() - 1;
 
                // Subtracting the invalid values
                ans -= (size - 1) * same_cnt;
            }
        }
        // Printing the answer
        System.out.println(ans);
    }
 
    // Driver Code
    public static void main(String[] args)
    {
        // Given input
        int n = 5;
        int details[][] = {
            { 1, 4 }, { 2, 4 }, { 3, 3 }, { 4, 2 }, { 1, 2 }
        };
 
        // Function Call
        solve(details, n);
    }
}
 
// This code is contributed by Rohit Pradhan


Python3




# Python code for the above approach
def solve(details, N):
    adj_a = [0]*(N+1)
    adj_b = [0]*(N+1)
    for i in range(N+1):
        adj_a[i] = []
        adj_b[i] = []
 
    for i in range(N):
       
        # Storing pairs with same first values
        adj_a[details[i][0]].append(details[i][1])
         
        # Storing pairs with same second values
        adj_b[details[i][1]].append(details[i][0])
 
    # Total ways to choose a triplet from n pairs is nC3
    ans = (N * (N-1)*(N-2))/6
 
    for i in range(1, N+1):
       
        # Size to keep record of the elements with same first values
        size = len(adj_a[i])
        for u in adj_a[i]:
           
                # Count of pairs that forms invalid triplets
            same_cnt = len(adj_b[u]) - 1
             
            # Subtracting the invalid values
            ans -= (size-1) * same_cnt
 
    # Printing the answer
    print(int(ans))
 
n = 5
details = [[1, 4],
           [2, 4],
           [3, 3],
           [4, 2],
           [1, 2]]
# Function call
solve(details, n)
 
# This code is contributed by lokeshmvs21.


C#




using System;
using System.Collections.Generic;
 
public class GFG {
 
  public static void solve(int[, ] details, int N)
  {
     
    // ArrayList to store the pairs with
    // common values
    /*List<int>[] adj_a = new List[N + 1];
        List<int>[] adj_b = new List[N + 1];*/
    List<int>[] adj_a = new List<int>[ N + 1 ];
    List<int>[] adj_b = new List<int>[ N + 1 ];
    for (int i = 0; i < N + 1; i++) {
      adj_a[i] = new List<int>();
      adj_b[i] = new List<int>();
    }
 
    for (int i = 0; i < N; i++) {
 
      // Storing pairs with same first values
      adj_a[details[i, 0]].Add(details[i, 1]);
 
      // Storing pairs with same second values
      adj_b[details[i, 1]].Add(details[i, 0]);
    }
 
    // Total ways to choose a triplet from
    // n pairs is nc3
    int ans = (N * (N - 1) * (N - 2)) / 6;
 
    for (int i = 1; i < N + 1; i++) {
 
      // Size to keep record of the elements
      // with same first values
      int size = adj_a[i].Count;
 
      for (int u = 0; u < adj_a[i].Count; u++) {
 
        // Count of pairs that forms
        // invalid triplets
        int same_cnt = adj_b[adj_a[i][u]].Count - 1;
 
        // Subtracting the invalid values
        ans -= (size - 1) * same_cnt;
      }
    }
    // Printing the answer
    Console.WriteLine(ans);
  }
 
  static public void Main()
  {
 
    // Given input
    int n = 5;
    int[, ] details = {
      { 1, 4 }, { 2, 4 }, { 3, 3 }, { 4, 2 }, { 1, 2 }
    };
 
    // Function Call
    solve(details, n);
  }
}
 
// This code is contributed by akashish__


Javascript




// JavaScript code for the above approach
function solve(details, N)
{
 
  // Vector to store the pairs with
  // common values
  let adj_a = new Array(N + 1);
  let adj_b = new Array(N + 1);
  for (let i = 0; i <= N; i++) {
    adj_a[i] = [];
    adj_b[i] = [];
  }
  for (let i = 0; i < N; i++) {
    // Storing pairs with same first values
    adj_a[details[i][0]].push(details[i][1]);
 
    // Storing pairs with same second values
    adj_b[details[i][1]].push(details[i][0]);
  }
 
  // Total ways to choose a triplet from
  // n pairs is nc3
  let ans = (N * (N - 1) * (N - 2)) / 6;
 
  for (let i = 1; i < N + 1; i++) {
    // Size to keep record of the elements
    // with same first values
    let size = adj_a[i].length;
 
    for (let u of adj_a[i]) {
      // Count of pairs that forms
      // invalid triplets
      let same_cnt = adj_b[u].length - 1;
 
      // Subtracting the invalid values
      ans -= (size - 1) * same_cnt;
    }
  }
  // Printing the answer
  console.log(ans);
}
 
// Driver's code
 
// Given input
let n = 5;
let details = [
  [1, 4],
  [2, 4],
  [3, 3],
  [4, 2],
  [1, 2],
];
 
// Function Call
solve(details, n);
 
// This code is contributed by Ishankhandelwals.


above approach:

Output

8

Time Complexity: O(N), the loop run once for every first value.
Auxiliary Space: O(N), where N is the size of the adjacency list



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads