Connected Components || DFS || Easy to Understand
Key Intuitions--> For two nodes to be reachable they should lie in the same connected component.
--> The AND operation can never increase any value. So for a co
# Key Intuitions
 --> `For two nodes to be reachable they should lie in the same connected component.`
--> `The AND operation can never increase any value. So for a connected component the AND of all edges can be considered as minimum.`

# Approach
- Keep track of a common parent for each member of a connected component in a parent vector (**par** in my code).
- For each common parent store the minimum path weight which is the AND of all edges that lie in the component (**cost** in my code).
- Start the DFS similar to finding connected compnents.

# Complexity
- Time complexity: O (V + E)

- Space complexity: O (V + E)

# Code
```cpp []
class Solution {

private:
    void dfs(vector<vector<vector<int>>> &g, vector<int> &vis, int node, vector<int> &par, vector<int> &cost, int &parent){
        vis[node] = 1;
        par[node] = parent;
        for (vector<int> &x: g[node]){
            int child = x[0], wt = x[1];
            cost[parent] &= wt; // ensuring AND operation with every edge of the current connected component

            if (vis[child]) continue;
            dfs(g, vis, child, par, cost, parent);
        }
    }


public:
    vector<int> minimumCost(int n, vector<vector<int>>& edges, vector<vector<int>>& query) {
        vector<int> par(n);
        vector<int> cost(n, INT_MAX);
        vector<int> vis(n, 0);

        // Building the graph
        vector<vector<vector<int>>> g(n);
        for (vector<int> &x: edges){
            g[x[0]].push_back({x[1], x[2]});
            g[x[1]].push_back({x[0], x[2]});
        }

        int parent = 0; // common parent for connected components
        for (int i = 0; i < n; i++){
            if (!vis[i]) dfs(g, vis, i, par, cost, parent);
            parent++; // different parent for next connected component
        }
        vector<int> ans;
        for (vector<int> &x: query){
            if (par[x[0]] == par[x[1]]){ // both the edges are reachable
                ans.push_back(cost[par[x[0]]]);
            } else {
                ans.push_back(-1);
            }
        }
        return ans;
    }
};
```
# **If you found this useful**
![image.png](https://assets.leetcode.com/users/images/67de95e1-3198-4cab-894f-6a579ed7bf0a_1742496065.1598873.png)

['Depth-First Search', 'Graph', 'C++']