Skip to content
  • Home
  • Contact Us
  • About Us
  • Privacy Policy
  • DMCA
  • Linkedin
  • Pinterest
  • Facebook
thecscience

TheCScience

TheCScience is a blog that publishes daily tutorials and guides on engineering subjects and everything that related to computer science and technology

  • Home
  • Human values
  • Microprocessor
  • Digital communication
  • Linux
  • outsystems guide
  • Toggle search form
HackerRank Crab Graphs Problem Solution

HackerRank Crab Graphs Problem Solution

Posted on May 19, 2023May 19, 2023 By Yashwant Parihar No Comments on HackerRank Crab Graphs Problem Solution

In this post, we will solve HackerRank Crab Graphs Problem Solution.

A crab is an undirected graph which has two kinds of vertices: 1 head, and K feet , and exactly K edges which join the head to each of the feet.( 1 <= K <= T, where T is given)

Given an undirected graph, you have to find in it some vertex-disjoint subgraphs where each one is a crab . The goal is to select those crabs in such a way that the total number of vertices covered by them is maximized.

Note: two graphs are vertex-disjoint if they do not have any vertices in common. 

Input Format

The first line of input contains a single integer C. C test-cases follow. The first line of each test-case contains three integers N, T, and M (the number of nodes, max number of feet in the crab graph, and number of edges, respectively). Each of next M lines contains two space separated values v1i, v2i meaning that the there is an edge between vertices v1i and v2i. Note that the graph doesn’t have parallel edges or loops.

Constraints

  • 1 <= C <= 10
  • 2 <= T <= 100
  • 2 <= N <= 100
  • 0 <= M <= N * (N-1)/2
  • 1 <= v1i <= N
  • 1 <= v2i <= N

Output Format

For each test-case, output a single integer indicating the maximum number of vertices which can be covered by vertex-disjoint sub-graphs of crab- graphs.

Sample Input

2  
8 2 7  
1 4  
2 4  
3 4  
5 4  
5 8  
5 7  
5 6  
6 3 8  
1 2  
2 3  
3 4  
4 5  
5 6  
6 1  
1 4  
2 5

Sample Output

6  
6

Explanation

Test #1: The graph for this test-case below. Because T = 2, each crab can have a maximum of 2 feet => each crab can cover a maximum of 3 nodes. We can cover 6 nodes of this graph with these two crabs: One of the crabs has 4 as its head and 1 and 3 as its feet, the other crab has 5 as its head and 7 and 8 as its feet. No additional crabs can be added.

The above is not a unique solution: any combination of two crabs, with one head at 4 and one head at 5, will suffice. We could have also chosen Head[4]feet[1,2] and Head[5]feet[6,7] as our two crabs.

Test #2: The graph for this test-case below. We can cover all 6 nodes using two crabs. One of the crabs has 2 as its head and 1 and 3 as its feet, the other crab has 5 as its head and 4 and 6 as its feet.

HackerRank Crab Graphs Problem Solution
HackerRank Crab Graphs Problem Solution

Table of Contents

  • Crab Graphs C Solution
  • Crab Graphs C++ Solution
  • Crab Graphs C Sharp Solution
  • Crab Graphs Java Solution
  • Crab Graphs JavaScript Solution
  • Crab Graphs Python Solution

Crab Graphs C Solution

#include <stdio.h>
#include <stdlib.h>
void remove_edge(int x,int y,int*connection,int**matrix);
void remove_point(int x,int*connection,int**matrix,int size);
void remove_point2(int x,int y,int*connection,int**matrix,int size);

int main()
{
  int i,j,k,C,T,N,M,x,y,ans,flag;
  int**matrix,*connection,*temp_connection;
  matrix=(int**)malloc(101*sizeof(int*));
  for(i=0;i<101;i++)
    matrix[i]=(int*)malloc(101*sizeof(int));
  connection=(int*)malloc(101*sizeof(int));
  temp_connection=(int*)malloc(101*sizeof(int));
  scanf("%d",&C);
  for(i=0;i<C;i++){
    scanf("%d%d%d",&N,&T,&M);
    ans=N;
    for(j=0;j<=N;j++)
      connection[j]=temp_connection[j]=0;
    for(j=0;j<=N;j++)
      for(k=0;k<=N;k++)
        matrix[j][k]=0;
    for(j=0;j<M;j++){
      scanf("%d%d",&x,&y);
      matrix[x][y]=matrix[y][x]=1;
      connection[x]++;
      connection[y]++;
    }
    for(j=1;j<=N;j++)
      if(!connection[j])
        ans--;
    do{
      flag=0;
      for(j=1;j<=N;j++)
        for(k=1;k<=N;k++)
          if(matrix[j][k]&&connection[j]==1&&connection[k]==1)
            remove_edge(j,k,connection,matrix);
          else if(matrix[j][k]&&connection[k]==1){
            flag=1;
            temp_connection[j]++;
          }
      for(j=1;flag&&j<=N;j++)
        if(temp_connection[j]>=T){
          flag=2;
          ans-=temp_connection[j]-T;
          remove_point(j,connection,matrix,N);
        }
        else if(temp_connection[j]&&temp_connection[j]==connection[j]){
          flag=2;
          remove_point(j,connection,matrix,N);
        }
      if(flag==1)
        for(j=1;flag==1&&j<=N;j++)
          for(k=1;flag==1&&k<=N;k++)
            if(matrix[j][k]&&temp_connection[j]&&connection[k]!=1){
              flag=2;
              remove_point2(k,j,connection,matrix,N);
            }
      for(j=1;j<=N;j++)
        temp_connection[j]=0;
    }while(flag);
    printf("%d\n",ans);
  }
  return 0;
}
void remove_edge(int x,int y,int*connection,int**matrix)
{
  connection[x]--;
  connection[y]--;
  matrix[x][y]=matrix[y][x]=0;
  return;
}
void remove_point(int x,int*connection,int**matrix,int size)
{
  int i;
  for(i=1;i<=size;i++)
    if(matrix[x][i])
      remove_edge(x,i,connection,matrix);
  return;
}
void remove_point2(int x,int y,int*connection,int**matrix,int size)
{
  int i;
  for(i=1;i<=size;i++)
    if(matrix[x][i]&&i!=y)
      remove_edge(x,i,connection,matrix);
  return;
}

Crab Graphs C++ Solution

#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
#include <array>
#include <queue>
#include <unordered_map>
#include <stdio.h>
using namespace std;

using edge_t = int64_t;

edge_t as_edge(int a, int b) {
    return ((edge_t)a << (edge_t)32) | b;
}

int get_a(edge_t e) {
    return e >> 32;
}

int get_b(edge_t e) {
    return e & 0xFFFFFFFF;
}

int main() {
    int C;
    scanf("%d", &C);
    while(C--) {
        int N, T, M;
        scanf("%d %d %d", &N, &T, &M);
        const int S = 200;
        const int D = 201;
        const int MAX = 202;
        std::array<std::vector<int>, 100> Graph;
        for(int i=0; i<M; ++i) {
            int a, b;
            scanf("%d %d", &a, &b);
            --a; --b;
            Graph[a].push_back(b);
            Graph[b].push_back(a);
        }
        
        std::array<std::vector<int>, MAX> RG;
        std::unordered_map<edge_t, int> EF;
        
        auto add_edge = [&RG, &EF](int from, int to, int c)
        {
            RG[from].push_back(to);
            EF[as_edge(from, to)] = c;
            RG[to].push_back(from);
            EF[as_edge(to, from)] = 0;            
        };
        
        for(int i=0; i<N; ++i) {
            int d = (int)Graph[i].size();
            int cap = std::min(d, T);
            
            add_edge(S, i*2, cap);
            add_edge(i*2+1, D, 1);
            
            for(int j=0; j<d; ++j) {
                int v1 = Graph[i][j];
                if(i < v1) {
                    add_edge(i*2, v1*2+1, 1);
                    add_edge(v1*2, i*2+1, 1);
                }
            }
        }
        
        std::queue<int> Q;
        std::array<int, MAX> Prev;
        int maxflow = 0;

        while(1) {
            while(!Q.empty()) {
                Q.pop();
            }
            Q.push(S);
            for(int v=0; v<2*N; ++v) {
                Prev[v] = -1;
            }
            Prev[S] = -2;
            Prev[D] = -1;
            while(!Q.empty()) {
                int v = Q.front();
                Q.pop();
                
                for(auto v1 : RG[v]) {
                    int f = EF[as_edge(v, v1)];
                    if((f > 0) && Prev[v1] == -1) {
                        Prev[v1] = v;
                        Q.push(v1);
                    }
                }
                
                if(Prev[D] != -1) {
                    break;
                }
            }
            
            if(Prev[D] == -1) {
                break;
            }
            
            int fc = 1000000;
            int v1 = D;
            while(Prev[v1] != -2) {  
                int v = Prev[v1];
                fc = std::min(fc, EF[as_edge(v, v1)]);
                v1 = v;
            }
            
            v1 = D;
            while(Prev[v1] != -2) {  
                int v = Prev[v1];
                EF[as_edge(v, v1)] -= fc;
                EF[as_edge(v1, v)] += fc;
                if(v == S) {
                    maxflow += fc;
                }
                v1 = v;
            }
        }
        
        printf("%d\n", maxflow);
    }
    return 0;
}

Crab Graphs C Sharp Solution

using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.Collections;
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.Serialization;
using System.Text.RegularExpressions;
using System.Text;
using System;

class Result
{

    /*
     * Complete the 'crabGraphs' function below.
     *
     * The function is expected to return an INTEGER.
     * The function accepts following parameters:
     *  1. INTEGER n
     *  2. INTEGER t
     *  3. 2D_INTEGER_ARRAY graph
     */

    private static List<List<int>> ed;
        private static bool[,] f;

        public static int crabGraphs(int n, int t, List<List<int>> graph)
        {
            int res = 0, n1, n2, mk;

            ed = new List<List<int>>();

            f = new bool[2 * n + 2, 2 * n + 2];


            for (int i = 0; i <= 2 * n + 1; i++)
            {
                ed.Add(new List<int>());
            }



            for (int i = 0; i < graph.Count; i++)
            {
                n1 = graph[i][0];
                n2 = graph[i][1];
                ed[2 * n1].Add(2 * n2 + 1);
                ed[2 * n2 + 1].Add(2 * n1);
                ed[2 * n2].Add(2 * n1 + 1);
                ed[2 * n1 + 1].Add(2 * n2);
                f[2 * n2 + 1, 2 * n1] = true;
                f[2 * n1 + 1, 2 * n2] = true;
            }

            for (int i = 1; i <= n; i++)
            {
                mk = 0;
                for (int j = 0; j < ed[2 * i].Count && mk < t; j++)
                {
                    n1 = 2 * i;
                    n2 = ed[n1][j];

                    if (f[n1, n2]) continue;

                    if (doIt(n1, n2, n))
                    {
                        res++;
                        mk++;

                    }

                }
            }
            return res;
        }

        private static bool doIt(int i, int t, int n)
        {
            int[] trac = new int[2*n + 2];
            int   yk, tk, y;
            bool[] b = new bool[2 * n + 2];
            Queue<int> q = new Queue<int>();
            q.Enqueue(t);
            trac[t] = i;
            b[i] = true;
            while (q.Count > 0)
            {
                
                yk = q.Peek();
                q.Dequeue();
                b[yk] = true;
                if (yk % 2 == 1 && !f[yk, 0])
                {
                    
                    f[yk, 0] = true;
                   
                    
                    while (trac[yk]!=0)
                    {
                        tk = yk;
                        yk = trac[yk];
                        f[yk, tk] = true;
                        f[tk, yk] = false;
                        
                    }
                    return true;
                }
                else
                {
                    y = ed[yk].Count;
                    for (int j = 0; j < y; j++)
                    {
                        if (!b[ed[yk][j]] && !f[yk, ed[yk][j]])
                        {
                            q.Enqueue(ed[yk][j]);
                            b[ed[yk][j]] = true;
                            trac[ed[yk][j]] = yk;
                        }
                    }
                }
            }
            
            return false;
        }

}

class Solution
{
    public static void Main(string[] args)
    {
        TextWriter textWriter = new StreamWriter(@System.Environment.GetEnvironmentVariable("OUTPUT_PATH"), true);

        int c = Convert.ToInt32(Console.ReadLine().Trim());

        for (int cItr = 0; cItr < c; cItr++)
        {
            string[] firstMultipleInput = Console.ReadLine().TrimEnd().Split(' ');

            int n = Convert.ToInt32(firstMultipleInput[0]);

            int t = Convert.ToInt32(firstMultipleInput[1]);

            int m = Convert.ToInt32(firstMultipleInput[2]);

            List<List<int>> graph = new List<List<int>>();

            for (int i = 0; i < m; i++)
            {
                graph.Add(Console.ReadLine().TrimEnd().Split(' ').ToList().Select(graphTemp => Convert.ToInt32(graphTemp)).ToList());
            }

            int result = Result.crabGraphs(n, t, graph);

            textWriter.WriteLine(result);
        }

        textWriter.Flush();
        textWriter.Close();
    }
}

Crab Graphs Java Solution

import java.io.*;
import java.math.*;
import java.text.*;
import java.util.*;
import java.util.regex.*;

public class Solution {

    /*
     * Complete the crabGraphs function below.
     */
    static int crabGraphs(int n, int t, int[][] graph) {
        List<Set<Integer>> adjacency = new ArrayList<>();
        for (int i = 0; i < n; i++) {
            adjacency.add(new HashSet<>());
        }
        for (int[] edge : graph) {
            int n1 = edge[0] - 1;
            int n2 = edge[1] - 1;
            adjacency.get(n1).add(n2);
            adjacency.get(n2).add(n1);
        }

        Deque<Integer> leaves = new ArrayDeque<>();
        int cover = n;
        for (int i = 0; i < n; i++) {
            if (adjacency.get(i).isEmpty()) {
                cover--;
            } else if (adjacency.get(i).size() == 1) {
                leaves.addLast(i);
            }
        }

        int[] legs = new int[n];
        while (!leaves.isEmpty()) {
            int leaf = leaves.removeFirst();
            if (legs[leaf] > 0) {
                continue;
            }

            if (adjacency.get(leaf).isEmpty()) {
                cover--;
            } else {
                int head = adjacency.get(leaf).stream().findAny().get();
                legs[head]++;
                if (legs[head] == t) {
                    for (int neighbor : adjacency.get(head)) {
                        adjacency.get(neighbor).remove(head);
                        if (adjacency.get(neighbor).size() == 1) {
                            leaves.addLast(neighbor);
                        }
                    }
                }
            }
        }
        return cover;
    }

    private static final Scanner scanner = new Scanner(System.in);

    public static void main(String[] args) throws IOException {
        BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(System.getenv("OUTPUT_PATH")));

        int c = scanner.nextInt();
        scanner.skip("(\r\n|[\n\r\u2028\u2029\u0085])*");

        for (int cItr = 0; cItr < c; cItr++) {
            String[] ntm = scanner.nextLine().split(" ");
            scanner.skip("(\r\n|[\n\r\u2028\u2029\u0085])*");

            int n = Integer.parseInt(ntm[0]);

            int t = Integer.parseInt(ntm[1]);

            int m = Integer.parseInt(ntm[2]);

            int[][] graph = new int[m][2];

            for (int graphRowItr = 0; graphRowItr < m; graphRowItr++) {
                String[] graphRowItems = scanner.nextLine().split(" ");
                scanner.skip("(\r\n|[\n\r\u2028\u2029\u0085])*");

                for (int graphColumnItr = 0; graphColumnItr < 2; graphColumnItr++) {
                    int graphItem = Integer.parseInt(graphRowItems[graphColumnItr]);
                    graph[graphRowItr][graphColumnItr] = graphItem;
                }
            }

            int result = crabGraphs(n, t, graph);

            bufferedWriter.write(String.valueOf(result));
            bufferedWriter.newLine();
        }

        bufferedWriter.close();

        scanner.close();
    }
}

Crab Graphs JavaScript Solution

'use strict';

const fs = require('fs');

process.stdin.resume();
process.stdin.setEncoding('utf-8');

let inputString = '';
let currentLine = 0;

process.stdin.on('data', function(inputStdin) {
    inputString += inputStdin;
});

process.stdin.on('end', function() {
    inputString = inputString.split('\n');

    main();
});

function readLine() {
    return inputString[currentLine++];
}

/*
 * Complete the 'crabGraphs' function below.
 *
 * The function is expected to return an INTEGER.
 * The function accepts following parameters:
 *  1. INTEGER n
 *  2. INTEGER t
 *  3. 2D_INTEGER_ARRAY graph
 */

function crabGraphs(n, t, graph) {
    const NODE_COUNT = n, CRAB_LIMIT = t;

    let nodesCount = [], nodesEdges = [];
    for (let j = 0; j <= NODE_COUNT; j++) {
        nodesCount[j] = 0;
        nodesEdges.push([]);
    }
    for (let edge of graph) {
        nodesCount[edge[0]] += 1;
        nodesCount[edge[1]] += 1;
        nodesEdges[edge[0]].push(edge[1]);
        nodesEdges[edge[1]].push(edge[0]);
    }

    let remove = true;
    while (remove && Math.max(...nodesCount) > CRAB_LIMIT) {
        remove = false;
        for (let j = 1; j <= NODE_COUNT; j++) {
            if (nodesCount[j] == 1) {
                let ind = nodesEdges[j][0]
                for (let lar of nodesEdges[ind]) {
                    if (nodesCount[lar] > CRAB_LIMIT) {
                        nodesCount[ind] -= 1;
                        nodesCount[lar] -= 1;
                        nodesEdges[ind].splice(nodesEdges[ind].indexOf(lar), 1);
                        nodesEdges[lar].splice(nodesEdges[lar].indexOf(ind), 1);
                        remove = true;
                    }
                }
            }
        }
    }

    while (Math.max(...nodesCount) > CRAB_LIMIT) {
        let ind = nodesCount.indexOf(Math.max.apply(null, nodesCount));
        let maxEdg = nodesEdges[ind][0];
        for (let edg of nodesEdges[ind])
            if (nodesEdges[edg].length > nodesEdges[maxEdg].length)
                maxEdg = edg;
        nodesCount[ind] -= 1;
        nodesCount[maxEdg] -= 1;
        nodesEdges[ind].splice(nodesEdges[ind].indexOf(maxEdg), 1);
        nodesEdges[maxEdg].splice(nodesEdges[maxEdg].indexOf(ind), 1);
    }
    let cou = nodesCount.filter(nc => nc > 0).length;
    return cou;
}

function main() {
    const ws = fs.createWriteStream(process.env.OUTPUT_PATH);

    const c = parseInt(readLine().trim(), 10);

    for (let cItr = 0; cItr < c; cItr++) {
        const firstMultipleInput = readLine().replace(/\s+$/g, '').split(' ');

        const n = parseInt(firstMultipleInput[0], 10);

        const t = parseInt(firstMultipleInput[1], 10);

        const m = parseInt(firstMultipleInput[2], 10);

        let graph = Array(m);

        for (let i = 0; i < m; i++) {
            graph[i] = readLine().replace(/\s+$/g, '').split(' ').map(graphTemp => parseInt(graphTemp, 10));
        }

        const result = crabGraphs(n, t, graph);

        ws.write(result + '\n');
    }

    ws.end();
}

Crab Graphs Python Solution

#!/bin/python3

import os
import sys

#
# Complete the crabGraphs function below.
#

from collections import defaultdict 
   
#This class represents a directed graph using adjacency matrix representation 
class Graph: 
   
    def __init__(self,graph): 
        self.graph = graph # residual graph 
        self. ROW = len(graph) 
        #self.COL = len(gr[0]) 
          
   
    '''Returns true if there is a path from source 's' to sink 't' in 
    residual graph. Also fills parent[] to store the path '''
    def BFS(self,s, t, parent): 
        #print("dans BFS({}, {})".format(s,t))
        # Mark all the vertices as not visited 
        visited =[False]*(self.ROW) 
          
        # Create a queue for BFS 
        queue=[] 
          
        # Mark the source node as visited and enqueue it 
        queue.append(s) 
        visited[s] = True
           
         # Standard BFS Loop 
        while queue: 
  
            #Dequeue a vertex from queue and print it 
            u = queue.pop(0) 
            #print("on dequeue {}".format(u))
            # Get all adjacent vertices of the dequeued vertex u 
            # If a adjacent has not been visited, then mark it 
            # visited and enqueue it 
            for ind, val in enumerate(self.graph[u]): 
                if visited[ind] == False and val > 0 : 
                    #print("on rajoute {}".format(ind))
                    queue.append(ind) 
                    visited[ind] = True
                    parent[ind] = u 

        #print("Fin BFS, on imprime parent:")
        #for i, p in enumerate(parent): print("parent[{}] = {}".format(i, p))
        
        # If we reached sink in BFS starting from source, then return 
        # true, else false 
        return True if visited[t] else False
              
      
    # Returns tne maximum flow from s to t in the given graph 
    def FordFulkerson(self, source, sink): 
  
        # This array is filled by BFS and to store path 
        parent = [-1]*(self.ROW) 

        #print("on imprime parent:")
        #for i, p in enumerate(parent): print("parent[{}] = {}".format(i, p))
  
        max_flow = 0 # There is no flow initially 
  
        # Augment the flow while there is path from source to sink 
        while self.BFS(source, sink, parent) : 
  
            # Find minimum residual capacity of the edges along the 
            # path filled by BFS. Or we can say find the maximum flow 
            # through the path found. 
            path_flow = sys.maxsize 
            s = sink 
            while(s !=  source): 
                path_flow = min (path_flow, self.graph[parent[s]][s]) 
                s = parent[s] 
  
            # Add path flow to overall flow 
            max_flow +=  path_flow 
  
            # update residual capacities of the edges and reverse edges 
            # along the path 
            v = sink 
            while(v !=  source): 
                u = parent[v] 
                self.graph[u][v] -= path_flow 
                self.graph[v][u] += path_flow 
                v = parent[v] 

        return max_flow 

def crabGraphs(n, t, graph):
    #
    # Write your code here.
    #
    g = Graph(graph)
    return g.FordFulkerson(0, 1)

if __name__ == '__main__':
    fptr = open(os.environ['OUTPUT_PATH'], 'w')

    c = int(input())

    for c_itr in range(c):
        ntm = input().split()

        n = int(ntm[0])

        t = int(ntm[1])

        m = int(ntm[2])

        graph = [[0 for _ in range(2*n+2)] for _ in range(2*n+2)]
        degree = [0 for _ in range(2*n+2)]
        for _ in range(m):
            u, v = list(map(int, input().rstrip().split()))
            
            graph[2*u][2*v+1] = 1
            degree[2*u] += 1
            graph[2*v][2*u+1] = 1
            degree[2*v] += 1
    
        for k in range(2, 2*n+2, 2):
            graph[0][k] = min(t, degree[k])
            graph[k+1][1]=1
        
        result = crabGraphs(n, t, graph)

        fptr.write(str(result) + '\n')

    fptr.close()
c, C#, C++, HackerRank Solutions, java, javascript, python Tags:C, cpp, CSharp, Hackerrank Solutions, java, javascript, python

Post navigation

Previous Post: HackerRank Jack goes to Rapture Problem Solution
Next Post: HackerRank Bead Ornaments Problem Solution

Related Posts

HackerRank Library Fine Problem Solution HackerRank Library Fine Problem Solution c
HackerRank Task Scheduling Problem Solution HackerRank Task Scheduling Problem Solution c
HackerRank Connected Cells in a Grid Problem Solution HackerRank Connected Cells in a Grid Solution c
HackerRank The Bomberman Game Problem Solution HackerRank The Bomberman Game Solution c
HackerRank Beautiful Quadruples Problem Solution HackerRank Beautiful Quadruples Problem Solution c
HackerRank ByteLandian Tours Problem Solution HackerRank ByteLandian Tours Problem Solution c

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Pick Your Subject
Human Values

Copyright © 2023 TheCScience.

Powered by PressBook Grid Blogs theme