HackerRank Tripartite Matching problem solution YASH PAL, 31 July 2024 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. Topics we are covering Toggle Problem solution in Python.Problem solution in Java.Problem solution in C++.Problem solution in C. 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) {“mode”:”full”,”isActive”:false} 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)); } } {“mode”:”full”,”isActive”:false} 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; } {“mode”:”full”,”isActive”:false} 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; } {“mode”:”full”,”isActive”:false} Algorithms coding problems solutions