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
  • Solutions
    • HackerRank
      • Algorithms Solutions
      • C solutions
      • C++ solutions
      • Java solutions
      • Python solutions
    • Leetcode Solutions
    • HackerEarth Solutions
  • Work with US
Programmingoneonone
Programmingoneonone

HackerRank The Value of Friendship problem solution

YASH PAL, 31 July 202424 January 2026

In this HackerRank The Value of Friendship problem solution You’re researching friendships between groups of n new college students where each student is distinctly numbered from 1 to n. At the beginning of the semester, no student knew any other student; instead, they met and formed individual friendships as the semester went on. The friendships between students are:

  • Bidirectional. If student a is friends with student b, then student b is also friends with student a.
  • Transitive. If student a is friends with student b and student b is friends with student c, then student a is friends with student c. In other words, two students are considered to be friends even if they are only indirectly linked through a network of mutual (i.e., directly connected) friends.

The purpose of your research is to find the maximum total value of a group’s friendships, denoted by total. Each time a direct friendship forms between two students, you sum the number of friends that each of the students has and add the sum to total.

You are given q queries, where each query is in the form of an unordered list of m distinct direct friendships between n students. For each query, find the maximum value of total among all possible orderings of formed friendships and print it on a new line.

HackerRank The Value of Friendship problem solution

HackerRank The Value of Friendship problem solution in Python.

def grow(n):
  res = 0
  for i in range(1, n):
    res += i*(i+1)
    #print("-->", i, res)
  return res
  
def mark(x):
  z = x
  while z: z = z[0]
  if x is not z: x[0] = z
  return z

def mark2(x):
  z = x
  while z and type(z) == list: z = z[0]
  if x is not z: x[0] = z
  return z

  
T = int(input())
for t in range(T):
  n, m = map(int, input().split())
  work = [[] for i in range(n)] 
  lost = 0
  for i in range(m):
    u, v = map(int, input().split())
    u -= 1
    v -= 1
    mu = mark(work[u])
    mv = mark(work[v])
    if mu is not mv:
      mu.append(mv)
    else:
      lost += 1
      
  no = 1
  dic = {}
  for i in range(n):
    z = mark2(work[i])
    if not z:
      z.append(no)
      z = no
      no += 1
      dic[z] = 1
    else:
      dic[z] += 1

  res = 0
  cur = 0    
  for v in sorted(dic.values(), reverse = True):
    res += grow(v) + (v-1) * cur
    cur += v*(v-1)
    #print(v, cur, res) 
    
  res += lost * cur
  print(res)  

The Value of Friendship problem solution in Java.

import java.util.*;

public class Solution {

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int t = in.nextInt();
        for(int a0 = 0; a0 < t; a0++){
            int n = in.nextInt();
            int m = in.nextInt();

            DisjointSets friendGroups = new DisjointSets(n);
            
            for(int a1 = 0; a1 < m; a1++){
                int x = in.nextInt();
                int y = in.nextInt();
                // your code goes here
                friendGroups.union(x - 1, y - 1);
            }
            
            List<Integer> groupSizes = friendGroups.setSizes();
            Collections.sort(groupSizes, Comparator.reverseOrder());

            long[] extra = new long[m];
            int idx = 0;
            for (int size : groupSizes) {
                for (int i = 1; i < size; i++) {
                    extra[idx++] = i;
                }
            }
            
            long totalFriendship = 0;
            long currentFriendship = 0;
            for (int i = 0; i < m; i++) {
                currentFriendship += 2L * extra[i];
                totalFriendship += currentFriendship;
            }
            System.out.println(totalFriendship);
        }
    }
    
    private static class DisjointSets {
        private int[] parent;
        private int[] size;
        
        public DisjointSets(int n) {
            parent = new int[n];
            size = new int[n];
            for (int i = 0; i < n; i++) {
                parent[i] = i;
                size[i] = 1;
            }
        }
        
        public void union(int a, int b) {
            int p = find(a);
            int q = find(b);
            if (p == q)
                return;
            if (size[p] < size[q]) {
                parent[p] = q;
                size[q] += size[p];
            }
            else {
                parent[q] = p;
                size[p] += size[q];
            }
        }
        
        public int find(int x) {
            while (x != parent[x]) {
                parent[x] = parent[parent[x]];
                x = parent[x];
            }
            return x;
        }
        
        public List<Integer> setSizes() {
            Set<Integer> sets = new HashSet<>();
            for (int x : parent)
                sets.add(find(x));
            List<Integer> sizes = new ArrayList<>();
            for (int x : sets)
                sizes.add(size[x]);
            return sizes;
        }
    }
}

Problem solution in C++.

#include <map>
#include <set>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <queue>
#include <stack>
#include <string>
#include <bitset>
#include <cstdio>
#include <limits>
#include <vector>
#include <climits>
#include <cstring>
#include <cstdlib>
#include <fstream>
#include <numeric>
#include <sstream>
#include <iostream>
#include <algorithm>
#include <unordered_map>

using namespace std;

vector<int> parent, setSz;


int find(int x)
{
	if (parent[x] == x)
		return x;
	return parent[x] = find(parent[x]);
}

int setunion(int a, int b)
{
	a = find(a);
	b = find(b);
	if (a == b)
		return setSz[a];
	if (setSz[a] < setSz[b])
		swap(a, b);
	parent[b] = a;
	setSz[a] += setSz[b];
	return setSz[a];
}

#define lint long long int


int main() {


	int t;
	cin >> t;
	for (int a0 = 0; a0 < t; a0++) {
		int n;
		int m;
		cin >> n >> m;

		parent.clear();
		parent.resize(n + 1);
		for (int i = 1; i <= n; i++)
			parent[i] = i;
		setSz.clear();
		setSz.resize(n + 1, 1);

		lint curFr = 0;
		lint res = 0;

		int same = 0;
	
		for (int a1 = 0; a1 < m; a1++) {
			int x;
			int y;
			cin >> x >> y;
			if (find(x) == find(y))
				same++;
			setunion(x, y);
			//lint oldSz1 = setSz[find(x)];
			//lint oldSz2 = setSz[find(y)];
			//lint newSz = setunion(x, y);
			//curFr += (newSz * (newSz - 1LL)) - (oldSz1 * (oldSz1 - 1LL)) - (oldSz2 * (oldSz2 - 1LL));
			//res += curFr;

			//cout << newSz << " " << curFr << endl;
		}
		set<int> clusters;
		vector<int> clusterSz;
		for (int i = 1; i <= n; i++)
		{
			int x = find(i);
			if (clusters.find(x) != clusters.end())
				continue;
			clusterSz.push_back(setSz[x]);
			clusters.insert(x);
		}
		sort(clusterSz.begin(), clusterSz.end());


		for (int i = clusterSz.size() - 1; i >= 0; i--)
		{
			for (int j = 2; j <= clusterSz[i]; j++)
			{
				curFr += j * (j - 1) - (j - 1) * (j - 2);
				res += curFr;
			}
		}
		res += curFr * same;


		cout << res << endl;
	}

	return 0;
}

Problem solution in C.

#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>
#include <string.h>
#include <stdlib.h>

int n, m;
int graph[500002][2];  // [0]-neighbor node, [1]-next
int gend;
int nodeedge[100001];
int used[100001];

int bfs(int v, int *edgen) {
  int q[100001];
  int i, j, qe=1;
  q[0]=v;
  used[v]=1;
  *edgen=nodeedge[v];
  for (i=0; i<qe; i++) {
    for (j=q[i]; j && (v=graph[j][0]); j=graph[j][1]) {
      if (!used[v]) {
        q[qe++]=v;
        used[v]=1;
        *edgen+=nodeedge[v];
      }
    }
  }
  return qe;
}

static int cmp(const void *p1, const void *p2) {
  return *((const int *)p2)-*((const int *)p1);
}

uint64_t solve(void) {
  uint64_t total=0, tt=0, t;
  int noden[100001], edgen, rededgen=0;
  int i, nni=0;
  for (i=1; i<=n; i++) {
    if (used[i])
      continue;
    noden[nni]=bfs(i, &edgen);
    if (edgen)
      rededgen+=edgen-noden[nni++]+1;
  }
  qsort(noden, nni, sizeof(int), cmp);
  for (i=0; i<nni; i++) {
    t=noden[i];
    total+=(t*(t+1)*(t-1))/3+(t-1)*tt;
    tt+=t*(t-1);
  }
  total+=tt*rededgen;
  return total;
}

int main(void) {
  int i, q, u, v;
  scanf("%dn", &q);
  while (q--) {
    scanf("%d%dn", &n, &m);
    gend=n+1;
    for (i=0; i<m; i++) {
      scanf("%d%dn", &u, &v);
      if (graph[u][0]) {
        graph[gend][0]=graph[u][0];
        graph[gend][1]=graph[u][1];
        graph[u][0]=v;
        graph[u][1]=gend++;
      } else {
        graph[u][0]=v;
      }
      if (graph[v][0]) {
        graph[gend][0]=graph[v][0];
        graph[gend][1]=graph[v][1];
        graph[v][0]=u;
        graph[v][1]=gend++;
      } else {
        graph[v][0]=u;
      }
      nodeedge[u]++;
    }
    printf("%"PRIu64"n", solve());
    memset(graph, 0, sizeof(graph));
    memset(nodeedge, 0, sizeof(nodeedge));
    memset(used, 0, sizeof(used));
    gend=0;
  }
  return 0;
}

Algorithms coding problems solutions AlgorithmsHackerRank

Post navigation

Previous post
Next post

Pages

  • About US
  • Contact US
  • Privacy Policy

Follow US

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