Disjoint Union Set 并查集

Equations are given in the format A / B = k, where A and B are variables represented as strings, and k is a real number (floating point number). Given some queries, return the answers. If the answer does not exist, return -1.0.

Example:
Given a / b = 2.0, b / c = 3.0.
queries are: a / c = ?, b / a = ?, a / e = ?, a / a = ?, x / x = ? .
return [6.0, 0.5, -1.0, 1.0, -1.0 ].

The input is: vector> equations, vector& values, vector> queries , where equations.size() == values.size(), and the values are positive. This represents the equations. Return vector.

According to the example above:

equations = [ ["a", "b"], ["b", "c"] ],
values = [2.0, 3.0],
queries = [ ["a", "c"], ["b", "a"], ["a", "e"], ["a", "a"], ["x", "x"] ]. 
 

The input is always valid. You may assume that evaluating the queries will result in no division by zero and there is no contradiction.

 

The implementation:

/**
 * Author sesiria, 2019
 * Dvaluate Division from LeetCode.399
 */
#include 
#include 
#include 
#include 
#include 

using namespace std;

class Solution {
private:
    struct dsjSet{
        unordered_map graph;
        unordered_map weight;
        
        string find(string p) {
            while(graph.count(p) && graph[p] != p) {
                p = graph[p];
            }
            return p;
        }
        
        void addEdge(string from, string to, double value) {            
            if (!weight.count(from)) weight[from] = value, graph[from]= from;
            if (!weight.count(to)) weight[to] = 1.0, graph[to] = to;
            // update values;
            double ratio = value * weight[to] / weight[from];
            
            auto p1 = find(from);
            auto p2 = find(to);
            for (auto & entry : graph) {
                if (find(entry.first) == p1)
                    weight[entry.first] *= ratio;
            }
            // relink the graph
            graph[p1] = p2;
        }
        
        double getWeight(string from, string to) {
            
            if (graph.count(from) == 0 || graph.count(from) == 0)
                return -1.0;
            
            if (find(from) != find(to))
                return -1.0;
            
            return weight[from] / weight[to];
        }
    };
public:
    vector calcEquation(vector>& equations, vector& values, vector>& queries) {
        dsjSet Graph;
        
        int N = equations.size();
        for (int i = 0; i < N; ++i)
            Graph.addEdge(equations[i][0], equations[i][1], values[i]);
        
        vector result;
        for (auto & query : queries)
            result.push_back(Graph.getWeight(query[0], query[1]));
        
        return result;
    }
};

int main()
{
    vector> equations = {{"x1","x2"},{"x2","x3"},{"x1","x4"},{"x2","x5"}};
    vector values = {3.0,0.5,3.4,5.6};
    vector> queries = {{"x2","x4"},{"x1","x5"},{"x1","x3"},{"x5","x5"},{"x5","x1"},{"x3","x4"},{"x4","x3"},{"x6","x6"},{"x0","x0"}};

    Solution sol;
    auto result = sol.calcEquation(equations, values, queries);

    return 0;
}

 

你可能感兴趣的:(C++,Algorithm)