-
Notifications
You must be signed in to change notification settings - Fork 3
/
antichain.cpp
75 lines (71 loc) · 1.53 KB
/
antichain.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
#include <vector>
#include <stack>
#include <mpc/naive.h>
#include <mpc/graph.h>
#include <mpc/antichain.h>
antichain maxantichain_from_minflow(Flowgraph<Edge::Minflow> &mf) {
std::vector<int> visited(mf.n+1);
auto v_r = [](int v){return (v+1)/2;}; // fg -> original graph
antichain mac;
auto dfs = [&mac, &v_r, &mf, &visited](auto &dfs, int s) {
if(visited[s])
return;
assert(s != mf.sink);
visited[s] = 1;
for(auto &[u,e] : mf.edge_out[s]) {
if(e->flow > e->demand) {
dfs(dfs, u);
}
}
for(auto &[u, e] : mf.edge_in[s]) {
dfs(dfs, u);
}
};
dfs(dfs, mf.source);
auto dfs2 = [&mac, &v_r, &mf, &visited](auto &dfs, int s) {
if(visited[s] != 1)
return;
visited[s] = 2;
for(auto &[u,e] : mf.edge_out[s]) {
if(e->flow > e->demand) {
dfs(dfs, u);
}
if(e->flow == e->demand && e->demand >= 1 && !visited[u]) {
mac.push_back(v_r(s));
visited[u] = 3;
}
}
for(auto &[u, e] : mf.edge_in[s]) {
dfs(dfs, u);
}
};
dfs2(dfs2, mf.source);
return mac;
}
bool is_antichain(antichain &ac, Graph &g) {
std::vector<bool> visited(g.n+1), antichain(g.n+1);
for(auto u:ac)
antichain[u] = 1;
auto dfs = [&g, &visited, &antichain](auto &dfs, int s)->bool {
if(visited[s])
return false;
if(antichain[s]) {
return true;
}
visited[s] = 1;
for(auto u:g.edge_out[s]) {
if(dfs(dfs, u))
return true;
}
return false;
};
for(auto u:ac) {
antichain[u] = 0;
if(dfs(dfs, u))
return false;
antichain[u] = 1;
for(int i=1; i<=g.n; i++)
visited[i] = 0;
}
return true;
}