Water Connection Problem | Practice | GeeksforGeeks

There are n houses and p water pipes in Geek Colony. Every house has at most one pipe going into it and at most one pipe going out of it. Geek needs to install pairs of tanks and taps in the colony according to the following guidelines.  
1. Every house with one outgoing pipe but no incoming pipe gets a tank on its roof.
2. Every house with only one incoming and no outgoing pipe gets a tap.
The Geek council has proposed a network of pipes where connections are denoted by three input values: ai, bi, di denoting the pipe of diameter di from house ai to house bi.
Find a more efficient way for the construction of this network of pipes. Minimize the diameter of pipes wherever possible.
Note: The generated output will have the following format. The first line will contain t, denoting the total number of pairs of tanks and taps installed. The next t lines contain three integers each: house number of tank, house number of tap, and the minimum diameter of pipe between them.

Example 1:
Input:
n = 9, p = 6
a[] = {7,5,4,2,9,3}
b[] = {4,9,6,8,7,1}
d[] = {98,72,10,22,17,66} 
Output: 
3
2 8 22
3 1 66
5 6 10
Explanation:
Connected components are 
3->1, 5->9->7->4->6 and 2->8.
Therefore, our answer is 3 
followed by 2 8 22, 3 1 66, 5 6 10.
 
Your Task:
You don't need to read input or print anything. Your task is to complete the function solve() which takes an integer n(the number of houses), p(the number of pipes),the array a[] , b[] and d[] (where d[i] denoting the diameter of the ith pipe from the house a[i] to house b[i]) as input parameter and returns the array of pairs of tanks and taps installed i.e ith element of the array contains three integers: house number of tank, house number of tap and the minimum diameter of pipe between them.  
 
Expected Time Complexity: O(n+p)
Expected Auxiliary Space: O(n+p)
 
Constraints:
1<=n<=20
1<=p<=50
1<=a[i],b[i]<=20
1<=d[i]<=100
0
milindprajapatmst19
This comment was deleted.
+1
rp212 weeks ago
Guys try to concise your code, otherwise things may messed up. If this problem can be solved using just for loops then why to go for other recursive DFS, topo sort etc.,        
 
       int in[21], out[21];       memset(in, -1, 21 << 2);       memset(out, -1, 21 << 2);       for(int i = 0; i < p; i++)           out[a[i]] = in[b[i]] = i;              vector<vector<int>> res;       for(int i = 1; i <= 20; i++)           if(out[i] != -1 && in[i] == -1)           {               int mn = 1000;               int x = i;               while(out[x] != -1)               {                   mn = min(mn, d[out[x]]);                   x = b[out[x]];               }               res.push_back({i, x, mn});           }       return res;
-1
tea_lover3 weeks ago
Simple Solution :
vector<vector<int>> solve(int n,int p,vector<int> a,vector<int> b,vector<int> d)
    {
        int A[n+1]={0};
        int vis[n+1]={0};
        vector<int>V(n+1,0);
        for(int i=1;i<=p;i++){
            A[a[i-1]] = b[i-1];
            V[a[i-1]] = d[i-1];
        }
        for(int i=1;i<=n;i++){
            if(vis[i]==0){
                int k = i;
                while(A[k] != 0 and A[k] != i){
                    V[i] = min(V[i],V[k]);
                    k = A[k];
                    vis[k]=1;
                }
                if(i != k) A[i] = k;
            }
        }
        vector<vector<int>>X;
        for(int i=1;i<=n;i++){
            if(vis[i]==0 and A[A[i]] != i and A[i] != 0){
                vector<int>temp(3);
                temp[0] = i;
                temp[1] = A[i];
                temp[2] = V[i];
                X.push_back(temp);
            }
        }
        return X;
}
0
vatsalsrivastava283 weeks ago
is this a graph problem?
 
+1
aaravarya11 month ago
C++ DFS solution
 pair<int,int> dfs(int index, vector<pair<int,int>> adj[], int mini)
    {
        if(adj[index].size()==0)
        return {index,mini};
        else
        {
            for(int i=0; i<adj[index].size(); i++)
            {
                if(adj[index][i].second< mini)
                mini=adj[index][i].second;
                
                return dfs(adj[index][i].first,adj,mini);
            }
        }
    }
    
    vector<vector<int>> solve(int n,int p,vector<int> a,vector<int> b,vector<int> d)
    {
        // code here
        vector<pair<int,int>> adj[n+1];
        vector<int> starting(n+1,true);
        for(int i=0; i<p; i++)
        {
            adj[a[i]].push_back({b[i],d[i]});
            starting[b[i]]=false;
        }
        vector<vector<int>> aarav;
        for(int i=1; i<=n; i++)
        {
            if(starting[i])
            {
                if(adj[i].size()==0)continue;
                vector<int> v;
                pair<int,int> p= dfs(i,adj,INT_MAX);
                v.push_back(i);
                v.push_back(p.first);
                v.push_back(p.second);
                aarav.push_back(v);
            }
        }
        sort(aarav.begin(),aarav.end());
        return aarav;
    }
0
sangamchoudhary71 month ago
for each component find toposort and while finding toposort also take care for minimum diameter
class Solution{
    public:
    void dfs(int node,vector<int> adj[],vector<bool> &vis,vector<int> &toposort,int &mini,vector<int> &d,unordered_map<int,int> &mp){
        vis[node] = true;
        for(auto &it : adj[node]){
            if(!vis[it]){
                int pos = mp[it];
                mini = min(mini,d[pos]);
                dfs(it,adj,vis,toposort,mini,d,mp);
            }
        }
        toposort.push_back(node);
    }
    vector<vector<int>> solve(int n,int p,vector<int> a,vector<int> b,vector<int> d){
        unordered_map<int,int> mp;
        for(int i=0;i<b.size();i++){
            mp[b[i]] = i;
        }
        
        vector<int> adj[n+1];
        for(int i=0;i<b.size();i++){
            adj[a[i]].push_back(b[i]);
        }
        
        vector<vector<int>> ans;
        vector<bool> vis(n+1);
        
        for(int i=1;i<n+1;i++){
            if(adj[i].empty() or mp.find(i) != mp.end()) continue;
            if(!vis[i]){
                int mini = 1e9;
                vector<int> toposort;
                dfs(i,adj,vis,toposort,mini,d,mp);
                ans.push_back({toposort.back(),toposort.front(),mini});
            }
        }
        
        return ans;
    }
};
-1
tthakare731 month ago
Please help me Optimize this → 0.3 TC 
but using large space
//Java Solution
class Solution 
{ 
    static class pair{
        int dest, dmeter;
        pair(int destination, int dm){
            dest = destination;
            dmeter = dm;
        }
    }
    
    static int check;
    
    public static int DFS(int src, int dest, HashMap<Integer, pair> map, int dimiter, HashSet<Integer> setOutlet){
        if(setOutlet.contains(dest)) {
            check = dest;
            dimiter = Math.min(dimiter, map.get(src).dmeter);
            return dimiter;
        }
        dimiter = DFS(dest, map.get(dest).dest, map, dimiter, setOutlet);
        dimiter = Math.min(dimiter, map.get(src).dmeter);
        return dimiter;
    }
    
    ArrayList<ArrayList<Integer>> solve(int n, int p, ArrayList<Integer> a ,ArrayList<Integer> b ,ArrayList<Integer> d) { 
         // code here
         HashSet<Integer> setOut = new HashSet<>();
         HashSet<Integer> setIn = new HashSet<>();
         HashSet<Integer> setOutlet = new HashSet<>();
         HashMap<Integer, pair> map = new HashMap<>();
         for(int i = 0; i < p; i++){
             setOut.add(b.get(i));
             setIn.add(a.get(i));
             map.put(a.get(i), new pair(b.get(i), d.get(i)));
         }
         
         ArrayList<Integer> inlet = new ArrayList<>();
         ArrayList<Integer> sortedTanks = a;
         Collections.sort(sortedTanks);
         
         for(int i = 0; i < p; i++){
             if(!setOut.contains(sortedTanks.get(i))){
                 inlet.add(sortedTanks.get(i));
             }
             
             if(!setIn.contains(b.get(i))){
                 setOutlet.add(b.get(i));
             }
         }
         
         ArrayList<ArrayList<Integer>> result = new ArrayList<>();;
         for(int i = 0; i < inlet.size(); i++){
             check = 0;
             ArrayList<Integer> result1 = new ArrayList<>();
             int dimiter = map.get(inlet.get(i)).dmeter;
             dimiter = DFS(inlet.get(i), map.get(inlet.get(i)).dest, map, dimiter, setOutlet);
             
             result1.add(inlet.get(i));
             result1.add(check);
             result1.add(dimiter);
             check = 0;
             result.add(result1);
            
         }
         return result;
     }
}
0
kritikasinha2562 months ago
PYTHON
class Solution:   def solve(self, n, p ,a, b, d):        bidx,aidx={},{}              for i in range(p):           aidx[a[i]]=i           bidx[b[i]]=i       #print(aidx)       #print(bidx)              start=[]       for i in a:           if i not in bidx:               start.append(i)       #print(start)              ans=[]       for node in start:           root=node           index=aidx[node]           mn=d[index]           while True:               index=aidx[node]               mn=min(d[index],mn)               if b[index] not in aidx:   #it has no further outgoing pipe                   ans.append([root,b[index],mn])                   #print(ans)                   break               else:                   node=b[index]              ans.sort()       return ans
+1
ashutoshrastogi2 months ago
Java Code
 
class Solution 
{ 
    static int ans=0;
    ArrayList<ArrayList<Integer>> solve(int n, int p, ArrayList<Integer> a ,ArrayList<Integer> b ,ArrayList<Integer> d) 
    {
        ArrayList<ArrayList<Integer>> res = new ArrayList<>();
        int i= 0;
        int[] ith_ends = new int[n+1]; 
        int[] ith_receives = new int[n+1];
        int[] dia = new int[n+1];
        
        for(i=0;i<p;i++){
            int q = a.get(i);
            int h = b.get(i);
            int t = d.get(i);
            
            ith_ends[q] = h;
            dia[q] = t;
            ith_receives[h] = q;
        }
        
        for(i=1;i<=n;i++){
            if(ith_receives[i] == 0 && ith_ends[i]!=0){
                ans = Integer.MAX_VALUE;
                //System.out.println("hi");
                int w = dfs(i,ith_ends,dia);
                
                ArrayList<Integer> tem = new ArrayList<>();
                tem.add(i);
                tem.add(w);
                tem.add(ans);
                
                res.add(tem);
            }
        }
        return res;
    }
    
    int dfs(int w, int[] ith_ends, int[]dia){
        if(ith_ends[w]==0)
            return w;
            
        ans = Math.min(ans,dia[w]);
        
        return(dfs(ith_ends[w],ith_ends,dia));
    }
} 
0
aloksinghbais022 months ago
C++ solution by applying DFS on connected graph having time complexity as O(n+e) if sorting is not considered and space complexity as O(n+e) with complete explanation is as follows :- 
 
Execution Time :- 0.0 / 1.1 sec
 
vector<int> adj[21]; // adjacency list for a connected component   int diam[21][21]; // diameter array      void dfs(int node,int &e,int &minDia){       e = node; // finding the last node in the current connected component       for(auto choice: adj[node]){ // traversing to all the nodes(choices) which are starting from node           minDia = min(minDia,diam[node][choice]); // minimise the diameter           dfs(choice,e,minDia); // applying dfs on childs or choices       }   }      vector<vector<int>> solve(int n,int p,vector<int> a,vector<int> b,vector<int> d){
       // initialize the diam 2d array       memset(diam,0,sizeof(diam));
              for(int i = 0; i < p; i++){           // assigning diameter of pipe a[i] to b[i] as d[i]           diam[a[i]][b[i]] = d[i];       }              unordered_set<int> s;       for(int i = 0; i < p; i++){           // creating a node from a[i] to b[i]           adj[a[i]].push_back(b[i]);           s.insert(b[i]);       }              //vector which will contain all the nodes which are the starting node of a new connected component       vector<int> st;       for(int i = 0; i < p; i++){           if(s.find(a[i]) == s.end())               st.push_back(a[i]);       }              // vector which will include our ans       vector<vector<int>> ans;       for(int i = 0; i < st.size(); i++){           // s is starting node of the connected component           // e is the ending node of the component           // minDia is the min diameter in the whole connected component           int s = st[i], e = 0, minDia = INT_MAX;           dfs(s,e,minDia);           // if starting (s) node is equal to ending (e) node then we won't include it in our ans           if(s == e) continue;           // otherwise include it in the ans           ans.push_back(vector<int>{s,e,minDia});       }       // sorting all the vectors present in ans as per need of the question       sort(ans.begin(),ans.end());              return (ans);   }
We strongly recommend solving this problem on your own before viewing its editorial. Do you still
                    want to view the editorial?
 Login to access your submissions. 

Problem


Contest

Reset the IDE using the second button on the top right corner.
Avoid using static/global variables in your code as your code is tested against multiple test cases and these tend to retain their previous values.
Passing the Sample/Custom Test cases does not guarantee the correctness of code. On submission, your code is tested against multiple test cases consisting of all possible corner cases and stress constraints.
You can access the hints to get an idea about what is expected of you as well as the final solution code.
You can view the solutions submitted by other users from the submission tab.