-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathLuogu_SP_2878.cpp
77 lines (77 loc) · 2.26 KB
/
Luogu_SP_2878.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
#include <bits/extc++.h>
using namespace std;
namespace pbds = __gnu_pbds;
istream& fin = cin;
ostream& fout = cout;
using ui = unsigned int;
using uli = unsigned long long int;
using li = long long int;
struct TarjanNode {
unordered_set<TarjanNode*> nxt;
size_t dfn, low, sz, id;
TarjanNode(void): dfn(~0) {}
void tarjan(vector<unordered_set<TarjanNode*>>& vDDC, stack<TarjanNode*>& stk,
size_t tm = 0, TarjanNode* fa = nullptr) {
dfn = low = tm++, sz = 1, stk.push(this);
for (TarjanNode* son : nxt)
if (!~son->dfn) {
son->tarjan(vDDC, stk, tm, this);
tm += son->sz, sz += son->sz;
low = min(low, son->low);
if (son->low >= dfn) {
vDDC.emplace_back();
while (stk.top() != son) vDDC.back().emplace(stk.top()), stk.pop();
vDDC.back().emplace(stk.top()), stk.pop();
vDDC.back().emplace(this);
}
} else if (son != fa)
low = min(low, son->dfn);
}
};
struct BinaryNode {
vector<BinaryNode*> nxt;
signed char color;
BinaryNode(void): color(~0) {}
bool checkBinaryNode(bool c = 0) {
if (color != -1) return color == c;
color = c;
for (BinaryNode* son : nxt)
if (!son->checkBinaryNode(!c)) return false;
return true;
}
};
int main(void) {
ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
size_t n, m;
fin >> n >> m;
if (n == 0) return 0;
vector<TarjanNode> mp(n);
for (size_t i = 0; i < n; ++i) mp[i].id = i;
for (TarjanNode& i : mp)
for (TarjanNode& j : mp)
if (&i != &j) i.nxt.emplace(&j);
while (m--) {
size_t x, y;
fin >> x >> y;
--x, --y;
mp[x].nxt.erase(&mp[y]), mp[y].nxt.erase(&mp[x]);
}
vector<unordered_set<TarjanNode*>> vDDC;
for (TarjanNode& i : mp)
if (!~i.dfn) {
stack<TarjanNode*> stk;
i.tarjan(vDDC, stk);
}
vector<size_t> ans(n, true);
for (unordered_set<TarjanNode*> const& s : vDDC) {
vector<BinaryNode> g(n);
for (TarjanNode& i : mp)
if (s.count(&i))
for (TarjanNode* j : i.nxt)
if (s.count(j)) g[i.id].nxt.emplace_back(&g[j->id]);
if (!g[(*s.begin())->id].checkBinaryNode())
for (TarjanNode* i : s) ans[i->id] &= false;
}
fout << accumulate(ans.begin(), ans.end(), size_t(0)) << '\n';
return main();
}