Open In App

Help geek to Avoid explosion

Last Updated : 05 Apr, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Geek is a chemical scientist who is performing an experiment to find an antidote to a poison. The experiment involves mixing some solutions in a flask. Based on the theoretical research Geek has done, he came up with an n * 2 array ‘mix’, where mix[i] = {X, Y} denotes solutions X and Y that needs to be mixed.

Also, from his past experience, it has been known that mixing some solutions leads to an explosion and thereby completely ruining the experiment. The explosive solutions are also provided as an m * 2 array ‘danger’ where danger[i] = {P, Q} denotes that if somehow solutions P and Q get into the same flask it will result in an explosion.

Help the Geek by returning an array ‘answer’ of size n, where answer[i] = “Yes” if it is safe to mix solutions in ‘mix[i]’ or else answer[i] = “No”.

Note: Geek should follow the order of mixing of solutions as it is in ‘mix’ otherwise the antidote will be ineffective. Also, Geek will not mix the solutions in ‘mix[i]’ once he gets to know that mixing them will result in an explosion. 

Examples:

Input: n = 5, m = 2
mix = {{1, 2}, {2, 3}, {4, 5}, {3, 5}, {2, 4}}
danger = {{1, 3}, {4, 2}}
Output: {“Yes”, “No”, “Yes”, “Yes”, “No”}
Explanation: Mixing the first solution(1 and 2) of ‘mix’ do not result in any kind of explosion hence answer[0] is “Yes”, while mixing 2 and 3 is not allowed because it will result in an explosion as 1 and 3 would be in same solution hence we have returned “No” as the answer for it. Mixing the third solution(4 and 5) and 4th solution(3 and 5) of ‘mix’ do not result in any kind of explosion hence answer[2] and answer[3] is “Yes”. While mixing 2 and 4 is not allowed because it will result in an explosion hence we have returned “No” as the answer for it.

Input: n = 3, m = 2
mix = {{1, 2}, {2, 3}, {1, 3}}
danger = {{1, 2}, {1, 3}}
Output: {“No”, “Yes”, “No”}
Explanation: Mixing solutions 1 and 2 is dangerous hence answer[0] = 7″No”, but solutions 2 and 3 can be mixed without any problem therefore answer[1] = “Yes”. Again, mixing solutions 1 and 3 is dangerous due to which answer[2] = “No”.

Approach: To solve the problem follow the below idea:

Geek should blend solutions in the same sequence as in the mixed array, thus we need to build a data structure that can group all the elements together that have already been mixed. Disjoint set data structure can verify the presence of two elements in log(n) time, thus we can utilize it.

Below are the steps for the above method:

  • First, each element must be made the parent of itself by being stored in the parent array.
  • We must determine whether there will be an explosion once each pair of the mix arrays has been combined. The representation of each element can be compared to do this process.
  • Use the union function to combine them if there is no risk of explosion. and save the response in a vector of string say res.

Below is the code for the above approach:

C++




#include <bits/stdc++.h>
using namespace std;
 
class GFG {
private:
    int find(int par[], int u)
    {
        if (par[u] == -1) {
            return u;
        }
        return find(par, par[u]);
    }
 
    void Union(int par[], int u, int v)
    {
        par[u] = v;
    }
 
public:
    vector<string> avoidExplosion(int mix[][2], int n,
                                    int danger[][2], int m)
    {
        int parent[n];
        memset(parent, -1, sizeof(parent));
        vector<string> res;
        for (int i = 0; i < n; i++) {
            int u = find(parent, mix[i][0] - 1);
            int v = find(parent, mix[i][1] - 1);
            int j = 0;
            for (; j < m; j++) {
                int p = find(parent, danger[j][0] - 1);
                int q = find(parent, danger[j][1] - 1);
                if ((u == p && v == q)
                    || (u == q && v == p)) {
                    res.push_back("No");
                    break;
                }
            }
            if (j == m && u == v) {
                res.push_back("Yes");
            }
            if (j == m && u != v) {
                res.push_back("Yes");
                Union(parent, u, v);
            }
        }
        return res;
    }
};
 
// Drivers code
int main()
{
    int mix[][2] = {
        { 1, 2 }, { 2, 3 }, { 4, 5 }, { 3, 5 }, { 2, 4 }
    };
    int n = 5;
    int danger[][2] = { { 1, 3 }, { 4, 2 } };
    int m = 2;
    GFG g;
    vector<string> res = g.avoidExplosion(mix, n, danger, m);
    for (string s : res) {
        cout << s << " ";
    }
    return 0;
}


Java




// Java code for the above approach:
import java.io.*;
import java.util.*;
 
class GFG {
    private int find(int[] par, int u)
    {
        if (par[u] == -1) {
            return u;
        }
        return find(par, par[u]);
    }
 
    private void union(int[] par, int u, int v)
    {
        par[u] = v;
    }
 
    ArrayList<String> avoidExplosion(int mix[][], int n,
                                    int danger[][], int m)
    {
        int[] parent = new int[n];
        Arrays.fill(parent, -1);
        ArrayList<String> res = new ArrayList<String>();
        for (int i = 0; i < mix.length; i++) {
            int u = find(parent, mix[i][0] - 1);
            int v = find(parent, mix[i][1] - 1);
            int j = 0;
            for (; j < m; j++) {
                int p = find(parent, danger[j][0] - 1);
                int q = find(parent, danger[j][1] - 1);
                if ((u == p && v == q)
                    || (u == q && v == p)) {
                    res.add("No");
                    break;
                }
            }
            if (j == m && u == v) {
                res.add("Yes");
            }
            if (j == m && u != v) {
                res.add("Yes");
                union(parent, u, v);
            }
        }
        return res;
    }
 
    // Drivers code
    public static void main(String[] args)
    {
        int mix[][] = {
            { 1, 2 }, { 2, 3 }, { 4, 5 }, { 3, 5 }, { 2, 4 }
        };
        int n = 5;
        int danger[][] = { { 1, 3 }, { 4, 2 } };
        int m = 2;
        GFG g = new GFG();
        System.out.println(
            g.avoidExplosion(mix, n, danger, m));
    }
}


Python3




# Python3 code for the above approach:
 
class GFG:
  # Find function to find the parent of a node in the given set
  def find(self, par, u):
    if par[u] == -1:
        return u
       
    return self.find(par, par[u])
 
  # Union function to perform union of two sets
  def Union(self, par, u, v):
      par[u] = v
 
  # Function to avoid explosion
  def avoidExplosion(self, mix, n, danger, m):
      parent = [-1] * n
      res = []
 
       # Loop through all the pairs of elements in the mix set
      for i in range(n):
          u = self.find(parent, mix[i][0] - 1)
          v = self.find(parent, mix[i][1] - 1)
          k = 0
          # Loop through all the pairs of elements in the danger set
          for j in range(m):
              k = k + 1             
              p = self.find(parent, danger[j][0] - 1)
              q = self.find(parent, danger[j][1] - 1)
               
              # If two elements in the mix set are connected through both the sets,
              # it will cause an explosion
              if (u == p and v == q) or (u == q and v == p):
                  res.append("No")
                  break
           
          # If no explosion occurs, add "Yes" to the result list
          if k == m and u == v:
            res.append("Yes")
           
          # If no explosion occurs and the two sets are not connected,
          # perform union of the sets and add "Yes" to the result list
          if k == m and u != v:
            res.append("Yes")
            self.Union(parent, u, v)
 
      return res
 
   
# Drivers code
if __name__ == "__main__":
  mix = [[1, 2], [2, 3], [4, 5], [3, 5], [2, 4]]
  n = 5
  danger = [[1, 3], [4, 2]]
  m = 2
  g = GFG()
  res = g.avoidExplosion(mix, n, danger, m)
 
  # Print the result
  for s in res:
      print(s, end=" ")


C#




// C# code for the above approach
using System;
using System.Collections.Generic;
 
public class GFG {
 
  // Find function to find the parent of a node in the
  // given set
  private int Find(int[] par, int u)
  {
    if (par[u] == -1) {
      return u;
    }
 
    return Find(par, par[u]);
  }
 
  // Union function to perform union of two sets
  private void Union(int[] par, int u, int v)
  {
    par[u] = v;
  }
 
  // Function to avoid explosion
  public List<string> AvoidExplosion(int[][] mix, int n,
                                    int[][] danger, int m)
  {
    int[] parent = new int[n];
    for (int i = 0; i < n; i++) {
      parent[i] = -1;
    }
 
    List<string> res = new List<string>();
 
    // Loop through all the pairs of elements in the mix
    // set
    for (int i = 0; i < mix.Length; i++) {
      int u = Find(parent, mix[i][0] - 1);
      int v = Find(parent, mix[i][1] - 1);
      int k = 0;
 
      // Loop through all the pairs of elements in the
      // danger set
      for (int j = 0; j < m; j++) {
        k = k + 1;
        int p = Find(parent, danger[j][0] - 1);
        int q = Find(parent, danger[j][1] - 1);
 
        // If two elements in the mix set are
        // connected through both the sets, it will
        // cause an explosion
        if ((u == p && v == q)
            || (u == q && v == p)) {
          res.Add("No");
          break;
        }
      }
 
      // If no explosion occurs, add "Yes" to the
      // result list
      if (k == m && u == v) {
        res.Add("Yes");
      }
 
      // If no explosion occurs and the two sets are
      // not connected, perform union of the sets and
      // add "Yes" to the result list
      if (k == m && u != v) {
        res.Add("Yes");
        Union(parent, u, v);
      }
    }
 
    return res;
  }
 
  static public void Main()
  {
 
    // Code
    int[][] mix
      = { new int[] { 1, 2 }, new int[] { 2, 3 },
         new int[] { 4, 5 }, new int[] { 3, 5 },
         new int[] { 2, 4 } };
    int n = 5;
    int[][] danger
      = { new int[] { 1, 3 }, new int[] { 4, 2 } };
    int m = 2;
 
    GFG g = new GFG();
    List<string> res
      = g.AvoidExplosion(mix, n, danger, m);
 
    // Print the result
    Console.Write("[");
    foreach(string s in res) { Console.Write(s + " "); }
    Console.Write("]");
  }
}


Javascript




// javascript code the following approach
 
class GFG {
  find(par, u) {
    if (par[u] == -1) {
      return u;
    }
    return this.find(par, par[u]);
  }
 
  union(par, u, v) {
    par[u] = v;
  }
 
  avoidExplosion(mix, n, danger, m) {
    const parent = new Array(n).fill(-1);
    const res = [];
    for (let i = 0; i < n; i++) {
      const u = this.find(parent, mix[i][0] - 1);
      const v = this.find(parent, mix[i][1] - 1);
      let j = 0;
      for (; j < m; j++) {
        const p = this.find(parent, danger[j][0] - 1);
        const q = this.find(parent, danger[j][1] - 1);
        if ((u == p && v == q) || (u == q && v == p)) {
          res.push("No");
          break;
        }
      }
      if (j == m && u == v) {
        res.push("Yes");
      }
      if (j == m && u != v) {
        res.push("Yes");
        this.union(parent, u, v);
      }
    }
    return res;
  }
}
 
// Driver code
const mix = [  [1, 2],
  [2, 3],
  [4, 5],
  [3, 5],
  [2, 4]
];
const n = 5;
const danger = [  [1, 3],
  [4, 2]
];
const m = 2;
const g = new GFG();
const res = g.avoidExplosion(mix, n, danger, m);
console.log(res.join(" "));


Output

[Yes, No, Yes, Yes, No]

Time Complexity: O(n*m*log(n))
Auxiliary Space: O(n)



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads