-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy path0399-evaluate-division.cpp
108 lines (94 loc) · 2.89 KB
/
0399-evaluate-division.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
98
99
100
101
102
103
104
105
106
107
108
class UF {
public:
string find(string s) {
auto is_parent_available = parents.count(s);
if (is_parent_available) {
auto p = parents[s], gp = find(p);
vals[s] *= vals[p];
parents[s] = gp;
}
return parents[s];
}
void join(string p, string c, double val) {
add(p), add(c);
auto px = find(p), py = find(c);
parents[px] = py;
vals[px] = val * vals[p] / vals[c];
}
bool has(string s, string c) {
if (!parents.count(s)) return false;
if (!parents.count(c)) return false;
if (find(s) == find(c)) return false;
return true;
}
double get_ans(string p, string c) {
return vals[p] / vals[c];
}
private:
unordered_map<string, double> vals;
unordered_map<string, string> parents;
void add(string s) {
if (parents.count(s)) return;
parents[s] = s;
vals[s] = 1.0;
}
};
class Solution {
// public:
// vector<double> calcEquation(vector<vector<string>>& eqs,
// vector<double>& vals,
// vector<vector<string>>& qs) {
// UF uf;
// for (int i = 0; i < vals.size(); i++) {
// auto p = eqs[i][0], c = eqs[i][1];
// auto weight = vals[i];
// uf.join(p, c, weight);
// }
// vector<double> res;
// for (auto q: qs) {
// auto calc = uf.has(q[0], q[1]) ? uf.get_ans(q[0], q[1]): -1;
// res.push_back(calc);
// }
// return res;
// }
public:
vector<double> calcEquation(vector<vector<string>>& equations,
vector<double>& values,
vector<vector<string>>& queries) {
vector<double> res(queries.size(), -1);
int i = 0;
for (auto &eq : equations)
unite(eq[0], eq[1], values[i++]);
i = 0;
for (auto &q : queries) {
string x = q[0], y = q[1];
if (isNode(x) && isNode(y) && find(x) == find(y))
res[i] = vals[x] / vals[y];
++i;
}
return res;
}
bool isNode(string x) {
return roots.count(x) > 0;
}
void add(string x) {
if (!isNode(x)) roots[x] = x, vals[x] = 1.0;
}
string find(string x) {
if (x != roots[x]) {
string rootX = roots[x];
roots[x] = find(rootX);
vals[x] = vals[x] * vals[rootX];
}
return isNode(x) ? roots[x] : x;
}
void unite(string x, string y, double v) {
add(x), add(y);
string rootX = find(x), rootY = find(y);
roots[rootX] = rootY;
vals[rootX] = v * vals[y] / vals[x];
}
private:
unordered_map<string, string> roots;
unordered_map<string, double> vals;
};