Skip to content
Programmingoneonone
Programmingoneonone
  • Engineering Subjects
    • Internet of Things (IoT)
    • Digital Communication
    • Human Values
  • Programming Tutorials
    • C Programming
    • Data structures and Algorithms
    • 100+ Java Programs
    • 100+ C Programs
    • 100+ C++ Programs
  • Solutions
    • HackerRank
      • Algorithms Solutions
      • C solutions
      • C++ solutions
      • Java solutions
      • Python solutions
    • Leetcode Solutions
    • HackerEarth Solutions
  • Work with US
Programmingoneonone
Programmingoneonone

HackerRank Tripartite Matching problem solution

YASH PAL, 31 July 202424 January 2026

In this HackerRank Tripartite Matching problem solution, You are given 3 unweighted, undirected graphs, G1, G2, and G3, with n vertices each, where the kth graph has mk edges and the vertices in each graph are numbered from 1 through n.

Find the number of ordered triples (a,b,c), where 1 <= a, b, c <= n a != b, b != c, c != a, such that there is an edge (a,b) in G1, an edge (b,c) in G2, and an edge (c,a) in G3.

HackerRank Tripartite Matching problem solution

HackerRank Tripartite Matching problem solution in Python.

#!/bin/python3

import os
import sys

#
# Complete the tripartiteMatching function below.
#
vertices = int(input())
graph = [[], [], [], []]
count = 0
G1 = 1
G2 = 2
G3 = 3

for i in range(1, 4):
    for j in range(0, vertices + 1):
        graph[i].append(None)

for i in range(1, 4):
    edges = int(input())
    for j in range(0, edges):
        edge = list(map(int, input().split(" ")))
        if graph[i][edge[0]] is None:
            graph[i][edge[0]] = set()
        graph[i][edge[0]].add(edge[1])
        if graph[i][edge[1]] is None:
            graph[i][edge[1]] = set()
        graph[i][edge[1]].add(edge[0])

for vertex in range(1, vertices + 1):
    verticesToG1 = graph[G1][vertex]
    if verticesToG1 is not None:
        verticesFromG2 = graph[G2][vertex]
        if verticesFromG2 is not None:
            for toVertex in verticesFromG2:
                verticesFromG3 = graph[G3][toVertex]
                if verticesFromG3 is not None:
                    count = count + len(verticesToG1.intersection(verticesFromG3))
        
print(count)

Tripartite Matching problem solution in Java.

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.InputMismatchException;

public class D {
    InputStream is;
    PrintWriter out;
    String INPUT = "";
    
    int[][] read(int n)
    {
        int m = ni();
        int[] from = new int[m];
        int[] to = new int[m];
        for(int i = 0;i < m;i++){
            from[i] = ni()-1;
            to[i] = ni()-1;
        }
        return packU(n, from, to);
    }
    
    void solve()
    {
        int n = ni();
        int[][] ga = read(n);
        int[][] gb = read(n);
        int[][] gc = read(n);
        
        int S = (int)Math.sqrt(100000);
        long[][] gbb = new long[n][];
        long[][] gbc = new long[n][];
        for(int i = 0;i < n;i++){
            if(gb[i].length >= S){
                gbb[i] = new long[(n>>>6)+1];
                for(int e : gb[i]){
                    gbb[i][e>>>6] |= 1L<<e;
                }
            }
            if(gc[i].length >= S){
                gbc[i] = new long[(n>>>6)+1];
                for(int e : gc[i]){
                    gbc[i][e>>>6] |= 1L<<e;
                }
            }
            Arrays.sort(gb[i]);
            Arrays.sort(gc[i]);
        }
        
        int na = ga.length;
        long ret = 0;
        for(int a = 0;a < na;a++){
            for(int b : ga[a]){
                if(gbb[b] != null){
                    if(gbc[a] != null){
                        for(int i = 0;i < (n>>>6)+1;i++){
                            ret += Long.bitCount(gbb[b][i]&gbc[a][i]);
                        }
                    }else{
                        for(int e : gc[a]){
                            if(gbb[b][e>>>6]<<~e<0)ret++;
                        }
                    }
                }else{
                    if(gbc[a] != null){
                        for(int e : gb[b]){
                            if(gbc[a][e>>>6]<<~e<0)ret++;
                        }
                    }else{
                        for(int i = 0, j = 0;i < gb[b].length && j < gc[a].length;){
                            if(gb[b][i] == gc[a][j]){
                                ret++; i++; j++;
                            }else if(gb[b][i] < gc[a][j]){
                                i++;
                            }else{
                                j++;
                            }
                        }
                    }
                }
            }
        }
        out.println(ret);
    }
    
    static int[][] packU(int n, int[] from, int[] to) {
        int[][] g = new int[n][];
        int[] p = new int[n];
        for (int f : from)
            p[f]++;
        for (int t : to)
            p[t]++;
        for (int i = 0; i < n; i++)
            g[i] = new int[p[i]];
        for (int i = 0; i < from.length; i++) {
            g[from[i]][--p[from[i]]] = to[i];
            g[to[i]][--p[to[i]]] = from[i];
        }
        return g;
    }
    
    void run() throws Exception
    {
        is = INPUT.isEmpty() ? System.in : new ByteArrayInputStream(INPUT.getBytes());
        out = new PrintWriter(System.out);
        
        long s = System.currentTimeMillis();
        solve();
        out.flush();
        if(!INPUT.isEmpty())tr(System.currentTimeMillis()-s+"ms");
    }
    
    public static void main(String[] args) throws Exception { new D().run(); }
    
    private byte[] inbuf = new byte[1024];
    private int lenbuf = 0, ptrbuf = 0;
    
    private int readByte()
    {
        if(lenbuf == -1)throw new InputMismatchException();
        if(ptrbuf >= lenbuf){
            ptrbuf = 0;
            try { lenbuf = is.read(inbuf); } catch (IOException e) { throw new InputMismatchException(); }
            if(lenbuf <= 0)return -1;
        }
        return inbuf[ptrbuf++];
    }
    
    private boolean isSpaceChar(int c) { return !(c >= 33 && c <= 126); }
    private int skip() { int b; while((b = readByte()) != -1 && isSpaceChar(b)); return b; }
    
    private double nd() { return Double.parseDouble(ns()); }
    private char nc() { return (char)skip(); }
    
    private String ns()
    {
        int b = skip();
        StringBuilder sb = new StringBuilder();
        while(!(isSpaceChar(b))){ // when nextLine, (isSpaceChar(b) && b != ' ')
            sb.appendCodePoint(b);
            b = readByte();
        }
        return sb.toString();
    }
    
    private char[] ns(int n)
    {
        char[] buf = new char[n];
        int b = skip(), p = 0;
        while(p < n && !(isSpaceChar(b))){
            buf[p++] = (char)b;
            b = readByte();
        }
        return n == p ? buf : Arrays.copyOf(buf, p);
    }
    
    private char[][] nm(int n, int m)
    {
        char[][] map = new char[n][];
        for(int i = 0;i < n;i++)map[i] = ns(m);
        return map;
    }
    
    private int[] na(int n)
    {
        int[] a = new int[n];
        for(int i = 0;i < n;i++)a[i] = ni();
        return a;
    }
    
    private int ni()
    {
        int num = 0, b;
        boolean minus = false;
        while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
        if(b == '-'){
            minus = true;
            b = readByte();
        }
        
        while(true){
            if(b >= '0' && b <= '9'){
                num = num * 10 + (b - '0');
            }else{
                return minus ? -num : num;
            }
            b = readByte();
        }
    }
    
    private long nl()
    {
        long num = 0;
        int b;
        boolean minus = false;
        while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
        if(b == '-'){
            minus = true;
            b = readByte();
        }
        
        while(true){
            if(b >= '0' && b <= '9'){
                num = num * 10 + (b - '0');
            }else{
                return minus ? -num : num;
            }
            b = readByte();
        }
    }
    
    private static void tr(Object... o) { System.out.println(Arrays.deepToString(o)); }
}

Problem solution in C++.

#include <iostream>
#include <cstdio>
#include <string.h>
#include <algorithm>
#include <vector>
#include <string>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <sstream>
#include <cmath>

typedef long long ll;
typedef unsigned int uint;

#define forn(i, n) for (int i = 0; i < (int)(n); i++)
#define forv(i, v) forn(i, v.size())
#define all(v) v.begin(), v.end()
#define pb push_back

using namespace std;

const int MAGIC = 32;

int n;
int bSize;

vector< vector<int> > g[3];
int m[3];

struct AdjSet {
set<int>* s;
uint* b;
AdjSet() {
s = NULL;
b = NULL;
}
};

vector<AdjSet> adj[2];

void buildAdjSets(vector<AdjSet>& as, const vector< vector<int> >& g) {
forn(i, n) {
if (g[i].size() < MAGIC) {
as[i].s = new set<int>();
for (int j : g[i]) {
as[i].s->insert(j);
}
} else {
as[i].b = new uint[bSize];
memset(as[i].b, 0, bSize * 4);
for (int j : g[i]) {
as[i].b[j >> 5] |= 1 << (j & 31);
}
}
}
}

int ones[1 << 16];

int calcIntersectionSize(const AdjSet& a1, const AdjSet& a2) {
if (a1.s != NULL && a2.s != NULL) {
int res = 0;
for (int v : *a1.s) {
if (a2.s->count(v)) res++;
}
return res;
}

if (a1.s != NULL || a2.s != NULL) {
if (a2.s != NULL) return calcIntersectionSize(a2, a1);
int res = 0;
for (int v : *a1.s) {
if (a2.b[v >> 5] & (1 << (v & 31))) res++;
}
return res;
}

int res = 0;
forn(i, bSize) {
uint x = a1.b[i] & a2.b[i];
res += ones[x >> 16] + ones[x & 65535];
}
return res;
}

int main() {
#ifdef NEREVAR_PROJECT
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
#endif
forn(i, 1 << 16) {
forn(j, 16) ones[i] += (i >> j) & 1;
}
cin >> n;
bSize = (n + 31) / 32;
forn(k, 3) {
cin >> m[k];
g[k] = vector< vector<int> >(n);
forn(i, m[k]) {
int x, y;
scanf("%d %d", &x, &y);
x--, y--;
g[k][x].push_back(y);
g[k][y].push_back(x);
}
}
forn(i, 2) {
adj[i] = vector<AdjSet>(n);
buildAdjSets(adj[i], g[i + 1]);
}
ll ans = 0;
forn(i, n) {
for (int j : g[0][i]) {
ans += calcIntersectionSize(adj[1][i], adj[0][j]);
}
}
cout << ans << endl;
return 0;
}


Problem solution in C.

#include <assert.h>
#include <limits.h>
#include <math.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char* readline();
char** split_string(char*);

struct edge{
    int from;
    int to;
};

bool precedge(struct edge e1, struct edge e2){
    return e1.from < e2.from || (e1.from == e2.from && e1.to < e2.to);
}

void setup(int n, int m, int** edges, struct edge *sortedge, int* edgebds){
    for(int i = 0; i < m; i++){
        sortedge[2*i].from = edges[i][0] - 1;
        sortedge[2*i].to = edges[i][1] - 1;
        sortedge[2*i + 1].from = edges[i][1] - 1;
        sortedge[2*i + 1].to = edges[i][0] - 1;
    }

    for(int i = 0; i < 2*m; i++){
        int curr = i;
        while(curr > 0){
            int next = (curr - 1)/2;
            if(precedge(sortedge[next], sortedge[curr])){
                struct edge temp = sortedge[curr];
                sortedge[curr] = sortedge[next];
                sortedge[next] = temp;
                curr = next;
            }
            else{
                break;
            }
        }
    }

    for(int i = 2*m - 1; i >= 0; i--){
        struct edge temp = sortedge[0];
        sortedge[0] = sortedge[i];
        sortedge[i] = temp;

        int curr = 0;
        while(true){
            int next = curr;
            if(2*curr + 1 < i && precedge(sortedge[next], sortedge[2*curr + 1])){
                next = 2*curr + 1;
            }
            if(2*curr + 2 < i && precedge(sortedge[next], sortedge[2*curr + 2])){
                next = 2*curr + 2;
            }
            if(next != curr){
                struct edge temp = sortedge[curr];
                sortedge[curr] = sortedge[next];
                sortedge[next] = temp;
                curr = next;
            }
            else{
                break;
            }
        }
    }

    edgebds[0] = 0;
    for(int i = 0; i < n; i++){
        int index = edgebds[i];
        while(index < 2*m && sortedge[index].from == i){
            index++;
        }
        edgebds[i + 1] = index;
    }
}

int tripartiteMatching(int n, int m1, int** g1, int m2, int** g2, int m3, int** g3) {
    struct edge sortedge1[2*m1], sortedge2[2*m2], sortedge3[2*m3];
    int edgebds1[n + 1], edgebds2[n + 1], edgebds3[n + 1];
    setup(n, m1, g1, sortedge1, edgebds1);
    setup(n, m2, g2, sortedge2, edgebds2);
    setup(n, m3, g3, sortedge3, edgebds3);

    int toreturn = 0;
    for(int i = 0; i < 2*m1; i++){
        int node2 = sortedge1[i].from;
        int node3 = sortedge1[i].to;
        int index2 = edgebds2[node2];
        int index3 = edgebds3[node3];
        while(index2 < edgebds2[node2 + 1] && index3 < edgebds3[node3 + 1]){
            int tonode2 = sortedge2[index2].to;
            int tonode3 = sortedge3[index3].to;
            if(tonode2 == tonode3){
                toreturn++;
                index2++;
                index3++;
            }
            else if(tonode2 < tonode3){
                index2++;
            }
            else{
                index3++;
            }
        }
    }
    return toreturn;

}

int main()
{
    FILE* fptr = fopen(getenv("OUTPUT_PATH"), "w");

    char* n_endptr;
    char* n_str = readline();
    int n = strtol(n_str, &n_endptr, 10);

    if (n_endptr == n_str || *n_endptr != '') { exit(EXIT_FAILURE); }

    char* m1_endptr;
    char* m1_str = readline();
    int m1 = strtol(m1_str, &m1_endptr, 10);

    if (m1_endptr == m1_str || *m1_endptr != '') { exit(EXIT_FAILURE); }

    int** g1 = malloc(m1 * sizeof(int*));

    for (int g1_row_itr = 0; g1_row_itr < m1; g1_row_itr++) {
        *(g1 + g1_row_itr) = malloc(2 * (sizeof(int)));

        char** g1_item_temp = split_string(readline());

        for (int g1_column_itr = 0; g1_column_itr < 2; g1_column_itr++) {
            char* g1_item_endptr;
            char* g1_item_str = *(g1_item_temp + g1_column_itr);
            int g1_item = strtol(g1_item_str, &g1_item_endptr, 10);

            if (g1_item_endptr == g1_item_str || *g1_item_endptr != '') { exit(EXIT_FAILURE); }

            *(*(g1 + g1_row_itr) + g1_column_itr) = g1_item;
        }
    }

    char* m2_endptr;
    char* m2_str = readline();
    int m2 = strtol(m2_str, &m2_endptr, 10);

    if (m2_endptr == m2_str || *m2_endptr != '') { exit(EXIT_FAILURE); }

    int** g2 = malloc(m2 * sizeof(int*));

    for (int g2_row_itr = 0; g2_row_itr < m2; g2_row_itr++) {
        *(g2 + g2_row_itr) = malloc(2 * (sizeof(int)));

        char** g2_item_temp = split_string(readline());

        for (int g2_column_itr = 0; g2_column_itr < 2; g2_column_itr++) {
            char* g2_item_endptr;
            char* g2_item_str = *(g2_item_temp + g2_column_itr);
            int g2_item = strtol(g2_item_str, &g2_item_endptr, 10);

            if (g2_item_endptr == g2_item_str || *g2_item_endptr != '') { exit(EXIT_FAILURE); }

            *(*(g2 + g2_row_itr) + g2_column_itr) = g2_item;
        }
    }

    char* m3_endptr;
    char* m3_str = readline();
    int m3 = strtol(m3_str, &m3_endptr, 10);

    if (m3_endptr == m3_str || *m3_endptr != '') { exit(EXIT_FAILURE); }

    int** g3 = malloc(m3 * sizeof(int*));

    for (int g3_row_itr = 0; g3_row_itr < m3; g3_row_itr++) {
        *(g3 + g3_row_itr) = malloc(2 * (sizeof(int)));

        char** g3_item_temp = split_string(readline());

        for (int g3_column_itr = 0; g3_column_itr < 2; g3_column_itr++) {
            char* g3_item_endptr;
            char* g3_item_str = *(g3_item_temp + g3_column_itr);
            int g3_item = strtol(g3_item_str, &g3_item_endptr, 10);

            if (g3_item_endptr == g3_item_str || *g3_item_endptr != '') { exit(EXIT_FAILURE); }

            *(*(g3 + g3_row_itr) + g3_column_itr) = g3_item;
        }
    }

    int result = tripartiteMatching(n, m1, g1, m2, g2, m3, g3);

    fprintf(fptr, "%dn", result);

    fclose(fptr);

    return 0;
}

char* readline() {
    size_t alloc_length = 1024;
    size_t data_length = 0;
    char* data = malloc(alloc_length);

    while (true) {
        char* cursor = data + data_length;
        char* line = fgets(cursor, alloc_length - data_length, stdin);

        if (!line) { break; }

        data_length += strlen(cursor);

        if (data_length < alloc_length - 1 || data[data_length - 1] == 'n') { break; }

        size_t new_length = alloc_length << 1;
        data = realloc(data, new_length);

        if (!data) { break; }

        alloc_length = new_length;
    }

    if (data[data_length - 1] == 'n') {
        data[data_length - 1] = '';
    }

    data = realloc(data, data_length);

    return data;
}

char** split_string(char* str) {
    char** splits = NULL;
    char* token = strtok(str, " ");

    int spaces = 0;

    while (token) {
        splits = realloc(splits, sizeof(char*) * ++spaces);
        if (!splits) {
            return splits;
        }

        splits[spaces - 1] = token;

        token = strtok(NULL, " ");
    }

    return splits;
}

Algorithms coding problems solutions AlgorithmsHackerRank

Post navigation

Previous post
Next post

Programmingoneonone

We at Programmingoneonone, also known as Programming101 is a learning hub of programming and other related stuff. We provide free learning tutorials/articles related to programming and other technical stuff to people who are eager to learn about it.

Pages

  • About US
  • Contact US
  • Privacy Policy

Practice

  • Java
  • C++
  • C

Follow US

  • YouTube
  • LinkedIn
  • Facebook
  • Pinterest
  • Instagram
©2026 Programmingoneonone | WordPress Theme by SuperbThemes