Heap vs Binary Search | C++
1.2 Greedy (Heap) using std::priority_queue
1.2 Greedy (Heap) using std::vector
2.1 BinSearch + BFS using std::queue
2.2 BinSearch + DFS using std::stack
$1.2$ Greedy (Heap) using `std::priority_queue`
$1.2$ Greedy (Heap) using `std::vector` 
$2.1$ BinSearch + $BFS$ using `std::queue`
$2.2$ BinSearch + $DFS$ using `std::stack`

```C++ [1.1]
class Solution {
public:
    int minMaxWeight(int n, std::vector<std::vector<int>> &edges, int threshold) { 
        using info = std::array<int, 2>;

        std::vector graph(n, std::vector<info>());
        
        for(std::vector<int> &edge: edges) std::swap(edge[0], edge[1]);
        for(std::vector<int> &edge: edges) {
            int u = edge[0], v = edge[1], w = edge[2];
            graph[u].push_back({v, w});
        }

        auto cmp = [](info &e1, info &e2) { return e1[1] > e2[1]; };
        std::priority_queue<info, std::vector<info>, decltype(cmp)> PQ(cmp);

        for(info &edge: graph[0]) PQ.push(edge);
        
        std::vector<bool> visit(n, 0); visit[0] = 1;
        int maxwt = 0;
        while(!PQ.empty()) {
            if(PQ.empty()) break;

            auto [node, wt] = PQ.top(); PQ.pop();
            if(visit[node]) continue;

            visit[node] = 1;
            maxwt = std::max(maxwt, wt);
            for(info &edge: graph[node]) PQ.push(edge);
        }

        return std::count(visit.begin(), visit.end(), 0) == 0? maxwt: -1;
    }
};
```
```C++ [1.2]
class Solution {
public:
    int minMaxWeight(int n, std::vector<std::vector<int>> &edges, int thresh) { 
        using info = std::array<int, 2>;

        std::vector graph(n, std::vector<info>());
        
        for(std::vector<int> &edge: edges) std::swap(edge[0], edge[1]);
        for(std::vector<int> &edge: edges) {
            int u = edge[0], v = edge[1], w = edge[2];
            graph[u].push_back({v, w});
        }

        auto cmp = [](info &e1, info &e2) { return e1[1] > e2[1]; };
        std::vector<info> heap;
        
        for(info &edge: graph[0]) heap.push_back(edge);
        std::make_heap(heap.begin(), heap.end(), cmp);

        std::vector<bool> visit(n, 0); visit[0] = 1;
        int maxwt = 0;
        while(!heap.empty()) {
            std::pop_heap(heap.begin(), heap.end(), cmp);
            
            auto [node, wt] = heap.back(); heap.pop_back();
            if(visit[node]) continue;

            visit[node] = true;
            maxwt = std::max(maxwt, wt);
            for(info &edge: graph[node]) {
                heap.push_back(edge);
                std::push_heap(heap.begin(), heap.end(), cmp);
            }
        }

        return std::count(visit.begin(), visit.end(), 0) == 0? maxwt : -1;
    }
};
```
```C++ [2.1]
class Solution {
public:
    int minMaxWeight(int n, std::vector<std::vector<int>>& edges, int threshold) {
        using info = std::array<int, 2>;

        std::vector graph(n, std::vector<info>());

        for(std::vector<int> &edge: edges) std::swap(edge[0], edge[1]);
        for(std::vector<int> &edge: edges) {
            int u = edge[0], v = edge[1], w = edge[2];
            graph[u].push_back({v, w});
        }

        auto cmp = [](const auto &e1, const auto &e2) { return e1[2] < e2[2]; };
        int minweight = (*std::min_element(edges.begin(), edges.end(), cmp))[2];
        int maxweight = (*std::max_element(edges.begin(), edges.end(), cmp))[2];
        
        auto bfs = [&](int m) -> bool {
            std::vector<bool> visit(n, 0);
            std::queue<int> qu;

            visit[0] = 1; qu.push(0);
            while(!qu.empty()) {
                int cur = qu.front();
                qu.pop();
                for(info &next: graph[cur]) {
                    if(next[1] > m or visit[next[0]]) continue;
                    visit[next[0]] = 1;
                    qu.push(next[0]);
                }
            }

            return std::count(visit.begin(), visit.end(), 1) == n? 1: 0;
        };

        int lo = minweight + 0, hi = maxweight + 1;
        int answer = -1;
        while(lo < hi) {
            int mid = (lo + hi) >> 1;
            
            if(bfs(mid)) {
                answer = (answer == -1)? mid: std::min(answer, mid);
                hi = mid;
            }
            else lo = mid + 1;
        }

        return answer;
    }
};
```
```C++ [2.2]
class Solution {
public:
    int minMaxWeight(int n, std::vector<std::vector<int>>& edges, int threshold) {
        using info = std::array<int, 2>;

        std::vector graph(n, std::vector<info>());

        for(std::vector<int> &edge: edges) std::swap(edge[0], edge[1]);
        for(std::vector<int> &edge: edges) {
            int u = edge[0], v = edge[1], w = edge[2];
            graph[u].push_back({v, w});
        }

        auto cmp = [](const auto &e1, const auto &e2) { return e1[2] < e2[2]; };
        int minweight = (*std::min_element(edges.begin(), edges.end(), cmp))[2];
        int maxweight = (*std::max_element(edges.begin(), edges.end(), cmp))[2];
        
        auto dfs = [&](int m) -> bool {
            std::vector<bool> visit(n, 0);
            std::stack<int> st;

            visit[0] = 1; st.push(0);
            while(!st.empty()) {
                int cur = st.top();
                st.pop();
                for(info &next: graph[cur]) {
                    if(next[1] > m or visit[next[0]]) continue;
                    visit[next[0]] = 1;
                    st.push(next[0]);
                }
            }

            return std::count(visit.begin(), visit.end(), 1) == n? 1: 0;
        };

        int lo = minweight + 0, hi = maxweight + 1;
        int answer = -1;
        while(lo < hi) {
            int mid = (lo + hi) >> 1;
            
            if(dfs(mid)) {
                answer = (answer == -1)? mid: std::min(answer, mid);
                hi = mid;
            }
            else lo = mid + 1;
        }

        return answer;
    }
};
```
['Binary Search', 'Graph', 'Heap (Priority Queue)', 'C++']