Union Find + DFS || Easy Approach✅✅
IntuitionThe problem involves answering queries about the minimum bitwise AND of weights on any path between two nodes. Since the graph is undirected and the ed
# Intuition
The problem involves answering queries about the minimum bitwise AND of weights on any path between two nodes. Since the graph is undirected and the edges have weights, the key insight is that the bitwise AND for a connected component of the graph is minimized by performing AND on all the edge weights in the component. Hence, we first determine the connected components and compute the minimum bitwise AND for each component. Then, for each query, we simply check if both nodes belong to the same component and return the precomputed result.

# Approach
1. **Union-Find (Disjoint Set Union)** is used to group nodes into connected components.
2. Construct an adjacency list from the given edges.
3. Use DFS on each connected component to compute the bitwise AND of all edge weights in that component.
4. Store this minimum cost for each component (root node).
5. For each query, check if both nodes are in the same component. If they are, return the component's cost. Otherwise, return -1.

# Complexity
- **Time complexity:** \( O(N + E + Q) \)

- **Space complexity:** \( O(N + E) \)
  - For storing adjacency list, parent, size, visited, and cost arrays.

# Code
```cpp []
class Solution {
public:
    vector<int> parent, size;

    int findParent(int node) {
        if (parent[node] == node) return node;
        return parent[node] = findParent(parent[node]);
    }

    void Union(int u, int v) {
        int pu = findParent(u);
        int pv = findParent(v);
        if (pu == pv) return;

        if (size[pu] > size[pv]) {
            size[pu] += size[pv];
            parent[pv] = pu;
        } else {
            size[pv] += size[pu];
            parent[pu] = pv;
        }
    }

    void dfs(int node, vector<vector<pair<int, int>>>& adj, vector<int>& vis, int& val) {
        vis[node] = 1;
        for (auto it : adj[node]) {
            if (val == -1) {
                val = it.second;
            } else {
                val &= it.second;
            }
            if (!vis[it.first]) {
                dfs(it.first, adj, vis, val);
            }
        }
    }

    vector<int> minimumCost(int n, vector<vector<int>>& edges, vector<vector<int>>& query) {
        parent.resize(n);
        size.resize(n, 1);
        for (int i = 0; i < n; i++) parent[i] = i;

        vector<vector<pair<int, int>>> adj(n);
        for (auto& it : edges) {
            adj[it[0]].emplace_back(it[1], it[2]);
            adj[it[1]].emplace_back(it[0], it[2]);
            Union(it[0], it[1]);
        }

        vector<int> vis(n, 0);
        vector<int> cost(n);
        for (int i = 0; i < n; i++) {
            if (!vis[i]) {
                int val = -1;
                dfs(i, adj, vis, val);
                int pu = findParent(i);
                cost[pu] = val;
            }
        }

        vector<int> ans(query.size());
        for (int i = 0; i < query.size(); i++) {
            int u = query[i][0];
            int v = query[i][1];
            int pu = findParent(u);
            int pv = findParent(v);

            if (pu == pv) {
                ans[i] = cost[pu];
            } else {
                ans[i] = -1;
            }
        }
        return ans;
    }
};
['Array', 'Bit Manipulation', 'Depth-First Search', 'Union Find', 'Graph', 'C++']