Skip to content

Commit 3285596

Browse files
authored
Create check-for-contradictions-in-equations.cpp
1 parent a34b919 commit 3285596

File tree

1 file changed

+114
-0
lines changed

1 file changed

+114
-0
lines changed
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
// Time: O(e + q)
2+
// Space: O(n)
3+
4+
// union find
5+
class Solution {
6+
public:
7+
bool checkContradictions(vector<vector<string>>& equations, vector<double>& values) {
8+
static const double EPS = 1e-5;
9+
UnionFind uf;
10+
for (int i = 0; i < size(equations); ++i) {
11+
if (!uf.union_set(equations[i][0], equations[i][1], values[i]) &&
12+
abs(uf.query_set(equations[i][0], equations[i][1]) - values[i]) > EPS) {
13+
return true;
14+
}
15+
}
16+
return false;
17+
}
18+
19+
private:
20+
class UnionFind {
21+
public:
22+
UnionFind() {
23+
}
24+
25+
pair<string, double> find_set(const string& x) {
26+
if (!set_.count(x)) {
27+
set_[x] = pair(x, 1.0);
28+
}
29+
const auto& [xp, xr] = set_[x];
30+
if (x != xp) {
31+
const auto& [pp, pr] = find_set(xp); // Path compression.
32+
set_[x] = pair(pp, xr * pr);
33+
}
34+
return set_[x];
35+
}
36+
37+
bool union_set(const string& x, const string& y, double r) {
38+
const auto& [xp, xr] = find_set(x);
39+
const auto& [yp, yr] = find_set(y);
40+
if (xp == yp) {
41+
return false;
42+
}
43+
if (rank_[xp] < rank_[yp]) { // Union by rank.
44+
set_[xp] = pair(yp, r * yr / xr);
45+
} else if (rank_[xp] > rank_[yp]) {
46+
set_[yp] = pair(xp, 1.0 / r * xr / yr);
47+
} else {
48+
set_[yp] = pair(xp, 1.0 / r * xr / yr);
49+
++rank_[xp];
50+
}
51+
return true;
52+
}
53+
54+
double query_set(const string& x, const string& y) {
55+
if (!set_.count(x) || !set_.count(y)) {
56+
return -1.0;
57+
}
58+
const auto& [xp, xr] = find_set(x);
59+
const auto& [yp, yr] = find_set(y);
60+
return (xp == yp) ? xr / yr : -1.0;
61+
}
62+
63+
private:
64+
unordered_map<string, pair<string, double>> set_;
65+
unordered_map<string, int> rank_;
66+
};
67+
};
68+
69+
// Time: O(e + q)
70+
// Space: O(n)
71+
// dfs
72+
class Solution2 {
73+
public:
74+
bool checkContradictions(vector<vector<string>>& equations, vector<double>& values) {
75+
unordered_map<string, vector<pair<string, double>>> adj;
76+
for (int i = 0; i < size(equations); ++i) {
77+
adj[equations[i][0]].emplace_back(equations[i][1], 1.0 / values[i]);
78+
adj[equations[i][1]].emplace_back(equations[i][0], values[i]);
79+
}
80+
unordered_map<string, double> lookup;
81+
const auto& iter_dfs = [&](const auto& u) {
82+
vector<string> stk = {u};
83+
lookup[u] = 1.0;
84+
while (!empty(stk)) {
85+
auto u = stk.back(); stk.pop_back();
86+
for (const auto& [v, k] : adj[u]) {
87+
if (lookup.count(v)) {
88+
if (!isclose(lookup[v], lookup[u] * k)) {
89+
return true;
90+
}
91+
continue;
92+
}
93+
lookup[v] = lookup[u] * k;
94+
stk.emplace_back(v);
95+
}
96+
}
97+
return false;
98+
};
99+
for (const auto& [u, _] : adj) {
100+
if (lookup.count(u)) {
101+
continue;
102+
}
103+
if (iter_dfs(u)) {
104+
return true;
105+
}
106+
}
107+
return false;
108+
}
109+
110+
private:
111+
bool isclose(double a, double b, double rel_tol = 1e-09, double abs_tol = 0.0) {
112+
return abs(a - b) <= max(rel_tol * max(abs(a), abs(b)), abs_tol);
113+
}
114+
};

0 commit comments

Comments
 (0)