Kruskal (MST): Really Special Subtree

  • + 0 comments

    C++ (more at https://github.com/IhorVodko/Hackerrank_solutions/tree/master , feel free to give a star:) )

    bool areNodesInTheSameTree(
        vector<bool> const & nodesVisited,
        std::unordered_map<int, vector<int>> const & nodeToNeighbours,
        int const nodeA,
        int const nodeB,
        int const nodesCount
    ){
        using namespace std;
        if(!(nodesVisited.at(nodeA) && nodesVisited.at(nodeB))){
            return false;
        }
        auto nodesVisitedBfs{vector<bool>(nodesCount + 1, false)};
        auto qBfs{queue<int>{}};
        qBfs.push(nodeA);
        nodesVisitedBfs.at(nodeA) = true;
        auto nodeCurrent{qBfs.front()};
        while(!qBfs.empty()){
            nodeCurrent = qBfs.front();
            qBfs.pop();
            for(auto const nodeNext: nodeToNeighbours.at(nodeCurrent)){
                if(nodeNext == nodeB){
                    return true;
                }
                if(nodesVisitedBfs.at(nodeNext)){
                    continue;
                }
                qBfs.push(nodeNext);
                nodesVisitedBfs.at(nodeNext) = true;
            }
        }
        return false;
    }
    
    int kruskals(
        int const nodesCount,
        std::vector<int> const & nodesFrom,
        std::vector<int> const & nodesTo,
        std::vector<int> const & edgeWeightes
    ){
        using namespace  std;
        auto weightToEdges{multimap<int, pair<int, int>>{}};
        for(size_t idx{0}; idx != edgeWeightes.size(); ++idx){
            weightToEdges.insert({edgeWeightes.at(idx), {nodesFrom.at(idx),
                nodesTo.at(idx)}});
        }
        cout << weightToEdges.size() << '\n';
        auto nodeToNeighbours{unordered_map<int, vector<int>>{}};
        auto weightSubtree{0};
        auto nodesVisited{vector<bool>(nodesCount + 1, false)};
        for(auto const & [weight, edge]: weightToEdges){
            if(::areNodesInTheSameTree(nodesVisited, nodeToNeighbours, edge.first,
                edge.second, nodesCount)
            ){
                continue;
            }
            nodeToNeighbours[edge.first].emplace_back(edge.second);
            nodeToNeighbours[edge.second].emplace_back(edge.first);
            nodesVisited.at(edge.first) = true;
            nodesVisited.at(edge.second) = true;
            weightSubtree += weight;
        }
        return weightSubtree;
    }