-
Notifications
You must be signed in to change notification settings - Fork 0
/
EvaluateDivision.cpp
97 lines (79 loc) · 3.04 KB
/
EvaluateDivision.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
struct Node {
string variable;
double value;
};
class UnionFind {
private:
// x = root[x].variable * root[x].value
unordered_map<string, Node> root;
unordered_map<string, int> rank;
public:
UnionFind(vector<vector<string>> equations) {
for (int i = 0; i < equations.size(); i++) {
root[equations[i][0]] = {equations[i][0], 1};
root[equations[i][1]] = {equations[i][1], 1};
}
}
Node find(string x) {
if (root[x].variable.empty()) { // represent undefined
return root[x];
}
if (x != root[x].variable) { // x is not the root node
// root[x].variable = p.variable * p.value
Node p = find(root[x].variable);
// x = p.variable * p.value*root[x].value
root[x].variable = p.variable;
root[x].value *= p.value;
}
return root[x];
}
void unionSet(string x, string y, double value) {
// x/y = value
Node rootX = find(x); // x = rootX.variable * rootX.value
Node rootY = find(y); // y = rootY.variable * rootY.value
// rootX.variable * rootX.value = rootY.variable * rootY.value * value
if (rootX.variable != rootY.variable) {
if (rank[rootX.variable] > rank[rootY.variable]) {
root[rootY.variable].variable = rootX.variable;
// rootY.variable = rootX.variable *
// rootX.value/rootY.value/value
root[rootY.variable].value = rootX.value / rootY.value / value;
} else if (rank[rootX.variable] < rank[rootY.variable]) {
root[rootX.variable].variable = rootY.variable;
// rootX.variable = rootY.variable *
// rootY.value/rootX.value*value
root[rootX.variable].value = rootY.value / rootX.value * value;
} else {
root[rootY.variable].variable = rootX.variable;
rank[rootX.variable] += 1;
// rootY.variable = rootX.variable *
// rootX.value/rootY.value/value
root[rootY.variable].value = rootX.value / rootY.value / value;
}
}
}
};
class Solution {
public:
vector<double> calcEquation(vector<vector<string>>& equations,
vector<double>& values,
vector<vector<string>>& queries) {
int n = equations.size();
UnionFind uf(equations);
for (int i = 0; i < n; i++) {
uf.unionSet(equations[i][0], equations[i][1], values[i]);
}
vector<double> answers;
for (int i = 0; i < queries.size(); i++) {
Node rootC = uf.find(queries[i][0]);
Node rootD = uf.find(queries[i][1]);
if (rootC.variable.empty() || rootD.variable.empty() ||
rootC.variable != rootD.variable) {
answers.push_back(-1);
} else {
answers.push_back(rootC.value / rootD.value);
}
}
return answers;
}
};