Last Updated: 13 Oct, 2021

Children And Chocolates

Hard
Asked in company
Intuit

Problem statement

‘N’ children are going home after their school break. Their roll numbers are assigned from 1 to ‘N’. There is a shop along the path to home from which they buy chocolates. You are given an array ‘CHOCOLATES’, representing the number of chocolates ‘ith’ child wants but the shop only has ‘C’ chocolates. Children can only take chocolate from that shop if the following two conditions are satisfied:

1. The student must be able to take all the chocolates that they want to take.

2. All their friends must be able to take all the chocolates they want to take.

There are ‘M’ pairs of friends among the children. Find the maximum number of children who can take all the chocolates they want?

Note:
If ‘A’ is a friend of ‘B’, then ‘B’ is also a friend of ‘A’.
Example:
Let the number of children be: 3
Let the number of chocolates be: 4
Let 1 and 2 be friends.
Let chocolates required by each child be: 3 2 2
Child 1 is a friend of child 2. If child 1 takes chocolate, shops need to have 5 chocolates which are greater than the actual amount present in the shop. So the maximum count of students that will take chocolates is 1 (child 3 can take chocolates as he needs 2 chocolates).
Input Format :
The first line of input contains an integer ‘T’, the number of test cases.

The first line of each test case contains three space-separated integers, ‘N’, ‘M’, and ‘C’, representing the number of children, the pair of friends, and the number of chocolates present in the shop, respectively.

The next ‘M’ lines contain two space-separated integers, ‘X' and 'Y', which signifies a friendship between ‘X’ and ‘Y’.

The ‘M’ + 1 line of each test case contains ‘N’ space-separated integers, representing the chocolates each child wants.
Output Format :
For each test case, print a single integer representing the maximum number of children who can take all the chocolates they want.

Print output of each test case in a separate line.
Note :
You do not need to print anything, it has already been taken care of. Just implement the given function.
Constraints :
1 <= T <= 5
1 <= N <= 10^3
1 <= M <= 10^4
1 <= X, Y <= N
1 <= CHOCOLATE[i] <= 10^3
1 <= C <= 10^3

Time Limit: 1 sec

Approaches

01 Approach

The basic idea is to find the number of connected components in the graph. We need to find the total sum of chocolates present in a connected component with their number of children to get the number of children present in the connected component with their total sum of chocolates present. We then need to find the maximum number of children whose sum of chocolates is smaller than equal to ‘C’.
 

Here is the algorithm :
 

  1. Create a graph (say, ‘GRAPH’) using the ‘FRIENDS’ array in the form of an adjacency list. (An array of lists in which ‘arr[i]’ represents the lists of vertices adjacent to the ‘ith’ vertex).
  2. Push the edges in the ‘GRAPH’.
  3. Create an array (say, ‘VISITED’) which will be used to mark all the visited vertices and initialize it with ‘FALSE’ for every vertex present in the ‘GRAPH’.
  4. Create a variable (say, ‘RES’) to store the count of maximum children.
  5. Call the ‘DFS’ function, DFS(‘GRAPH’, ‘U’, ‘VISITED’, ‘CHOCOLATES’) for every unvisited vertex to count for the number of connected components. where ‘U’ is an unvisited vertex and store its result in a variable (say, ‘TEMP’).
    1. Store ‘TEMP’ and number of children in that connected component in arrays (say ‘COUNT’ and ‘CHILDREN’ respectively).
    2. Call the HELPER(‘C’, ‘COUNT’, ‘CHILDREN’) to find the maximum number of children whose sum of chocolates is smaller than ‘C’.
  6. Finally, return the value returned by the HELPER function.

 

DFS(‘GRAPH’, ‘U’, ‘VISITED’, ‘CHOCOLATES’)

 

  1. Mark ‘U’ as visited in the ‘VISITED’ array.
  2. Iterate over all the adjacent vertices of the ‘U’ (say, iterator ‘V’).
    • If ‘VISITED[GRAPH[U][V]]’ is equal to ‘FALSE’
      • Update ‘VISITED[GRAPH[U][V]]’ as 1.
      • Call DFS on all adjacent vertices of ‘U’ while adding the chocolates of each friend.

 

HELPER function finds the maximum number of children that can get chocolates from the shop. For each value of ‘CHILDREN’, we have two options: whether to include the current value or not. So, we can obtain the maximum count by:

  1. Maximum count obtained by ‘N’ - 1 childrens, and ‘C’ chocolates (exclude ‘Nth’ children)
  2. Value of ‘Nth’ child plus the maximum value obtained by ‘N’ - 1 childrens and ‘C’ minus the chocolate required by a current number of childrens. ( include ‘Nth’ child)
     

HELPER(‘C’, ‘COUNT’, ‘CHILDREN’, ‘S’)  (where ‘N’ is the size of the ‘COUNT’ array).

 

  1. Base case
    • If ‘C’ or ‘S’  is equal to 0, return 0.
  2. Check if ‘COUNT[S - 1] is greater than ‘C’
    • Call the HELPER function by not including the current children.
  3. Else
    • Call the HELPER function two times by including the current children and not including the current children and return the maximum value.

02 Approach

The approach is similar to the previous approach. In this approach, we will use an array (say, ‘DP’) to store the recursive calls. 

How do we know we are calling the same function more than once?

Let ‘N’ be 3 and ‘C’ be 2.

We call HELPER function on values (3, 2)

(3, 2) if we include current value then it calls helper function on values (2, 1) ->(1, 1), (1, 0) and so on.

(3, 2) if we exclude current value then it calls helper function on values (2, 2) -> (1, 2), (1, 1)  and so on.

As we can see (1, 1) is called twice. For large values of ‘N’ and ‘C’ there can be many repeated recursive calls. To avoid that we can use memoization to store recursive calls.

 

Here is the algorithm :
 

HELPER(‘C’, ‘COUNT’, ‘CHILDREN’, ‘S’, ‘DP’)  (where ‘N’ is the size of the ‘COUNT’ array, ‘DP’ is the array used for memoization initialized with -1, and ‘S’ is the current index).
 

  1. Base case
    • If ‘S’ is equal to 0 or ‘C’ is equal to 0, return 0.
  2. Check if ‘DP[S - 1][C]’ is not equal to -1
    • Return ‘DP[S - 1][C]’.
  3. Check if ‘COUNT[S - 1] is greater than ‘C’
    • Call the HELPER function by not including the current children and store its value in the ‘DP’ array.
  4. Else
    • Call the HELPER function two times by including the current children and not including the current children and return the maximum value and store the value in the ‘DP’ array.

03 Approach

The approach is similar to the previous approach. In this approach, we will use the bottom-up approach to find the count of children for all possible numbers of chocolates from 1 to ‘W’. ‘DP[i]’ denotes the maximum number of children having ‘i’ number of chocolates. 
 

Here is the algorithm :

 

HELPER(‘C’, ‘COUNT’, ‘CHILDREN’, ‘S’)  (where ‘N’ is the size of the ‘COUNT’ array).
 

  1. Create an array (say, ‘DP’) of size ‘C’ initialized with 0.
  2. Run a loop from 1 to ‘S’ (say, iterator ‘i’)
    • Run a loop from 1 to ‘W’ (say, iterator ‘j’)
      • Check if ‘COUNT[i - 1] is smaller than equal to ‘W’
        • Update ‘DP[j]’ with value maximum of ‘DP[j]’ and ‘CHILDREN[i - 1]’ plus ‘DP[j - COUNT[i - 1]]’.
  3. Finally, return ‘DP[C]’.