69 lines
2.4 KiB
C++
69 lines
2.4 KiB
C++
// P3275 糖果。迭代 Kosaraju + 缩点 DAG 上的最长下界,O(n+k)。
|
|
#include <bits/stdc++.h>
|
|
using namespace std;
|
|
int main() {
|
|
ios::sync_with_stdio(false); cin.tie(nullptr);
|
|
int n, k; if (!(cin >> n >> k)) return 0;
|
|
vector<vector<pair<int,int>>> g(n);
|
|
vector<vector<int>> rg(n);
|
|
auto add = [&](int u, int v, int w) { g[u].push_back({v,w}); rg[v].push_back(u); };
|
|
for (int i = 0, x, a, b; i < k; ++i) {
|
|
cin >> x >> a >> b; --a; --b;
|
|
if (x == 1) { add(a,b,0); add(b,a,0); }
|
|
if (x == 2) add(a,b,1);
|
|
if (x == 3) add(b,a,0);
|
|
if (x == 4) add(b,a,1);
|
|
if (x == 5) add(a,b,0);
|
|
}
|
|
vector<bool> vis(n, false);
|
|
vector<int> order;
|
|
// 第一次 DFS:显式保存下一条边下标,退出时记录结束序。
|
|
for (int s = 0; s < n; ++s) if (!vis[s]) {
|
|
vector<pair<int,int>> st;
|
|
vis[s] = true; st.push_back({s,0});
|
|
while (!st.empty()) {
|
|
auto &[u,i] = st.back();
|
|
if (i == (int)g[u].size()) { order.push_back(u); st.pop_back(); }
|
|
else {
|
|
int v = g[u][i++].first;
|
|
if (!vis[v]) { vis[v] = true; st.push_back({v,0}); }
|
|
}
|
|
}
|
|
}
|
|
// 第二次 DFS:反图按逆结束序分组。
|
|
vector<int> comp(n, -1), size;
|
|
int count = 0;
|
|
reverse(order.begin(), order.end());
|
|
for (int s : order) if (comp[s] == -1) {
|
|
vector<int> st(1,s); comp[s] = count; int amount = 0;
|
|
while (!st.empty()) {
|
|
int u = st.back(); st.pop_back(); ++amount;
|
|
for (int v : rg[u]) if (comp[v] == -1) {
|
|
comp[v] = count; st.push_back(v);
|
|
}
|
|
}
|
|
size.push_back(amount); ++count;
|
|
}
|
|
vector<vector<pair<int,int>>> dag(count);
|
|
vector<int> indeg(count, 0), d(count, 1);
|
|
for (int u = 0; u < n; ++u) for (auto [v,w] : g[u]) {
|
|
if (comp[u] == comp[v]) {
|
|
if (w == 1) { cout << -1 << '\n'; return 0; }
|
|
} else {
|
|
dag[comp[u]].push_back({comp[v],w}); ++indeg[comp[v]];
|
|
}
|
|
}
|
|
queue<int> q;
|
|
for (int c = 0; c < count; ++c) if (indeg[c] == 0) q.push(c);
|
|
while (!q.empty()) {
|
|
int u = q.front(); q.pop();
|
|
for (auto [v,w] : dag[u]) {
|
|
d[v] = max(d[v], d[u]+w);
|
|
if (--indeg[v] == 0) q.push(v);
|
|
}
|
|
}
|
|
long long ans = 0;
|
|
for (int c = 0; c < count; ++c) ans += 1LL * size[c] * d[c];
|
|
cout << ans << '\n';
|
|
}
|