Update graph/tarjan.cc
Signed-off-by: subcrip <contact@subc.rip>
This commit is contained in:
parent
1ac86aa595
commit
cdc14e0060
|
@ -1,4 +1,14 @@
|
|||
namespace tarjan {
|
||||
struct mutex_cond {
|
||||
int v1; bool cond1;
|
||||
int v2; bool cond2;
|
||||
mutex_cond(int v1, bool cond1, int v2, bool cond2) : v1(v1), cond1(cond1), v2(v2), cond2(cond2) {}
|
||||
};
|
||||
struct inclusive_cond {
|
||||
int v1; bool cond1;
|
||||
int v2; bool cond2;
|
||||
inclusive_cond(int v1, bool cond1, int v2, bool cond2) : v1(v1), cond1(cond1), v2(v2), cond2(cond2) {}
|
||||
};
|
||||
// Returns the mapping between vertices and their affiliated sccs.
|
||||
vector<int> scc(const vector<vector<int>>& ch) {
|
||||
int n = ch.size();
|
||||
|
@ -25,7 +35,6 @@ namespace tarjan {
|
|||
}
|
||||
return br;
|
||||
}
|
||||
|
||||
// This method can eliminate redundant edges or self-loops
|
||||
vector<vector<int>> build_scc(const vector<vector<int>>& ch) {
|
||||
int n = ch.size();
|
||||
|
@ -65,4 +74,35 @@ namespace tarjan {
|
|||
}
|
||||
return res;
|
||||
}
|
||||
// indices start from 1, result has `n` items
|
||||
optional<vector<bool>> solve_twosat(int n, const vector<mutex_cond>& conditions) {
|
||||
vector<vector<int>> ch(2 * n + 1);
|
||||
for (auto&& [v1, cond1, v2, cond2] : conditions) {
|
||||
ch[(1 ^ cond1) * n + v1].emplace_back(cond2 * n + v2);
|
||||
ch[(1 ^ cond2) * n + v2].emplace_back(cond1 * n + v1);
|
||||
}
|
||||
auto sccno = scc(ch);
|
||||
for (int i = 1; i <= n; ++i) {
|
||||
if (sccno[i] == sccno[i + n]) {
|
||||
return nullopt;
|
||||
}
|
||||
}
|
||||
vector<bool> res;
|
||||
for (int i = 1; i <= n; ++i) {
|
||||
if (sccno[i] < sccno[i + n]) {
|
||||
res.emplace_back(false);
|
||||
} else {
|
||||
res.emplace_back(true);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
};
|
||||
// indices start from 1, result has `n` items
|
||||
optional<vector<bool>> solve_twosat(int n, const vector<inclusive_cond>& conditions) {
|
||||
vector<mutex_cond> trans_conds;
|
||||
for (auto&& [v1, cond1, v2, cond2] : conditions) {
|
||||
trans_conds.emplace_back(v1, cond1, v2, not cond2);
|
||||
}
|
||||
return solve_twosat(n, trans_conds);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue