「SCOI2011」糖果
阿新 • • 發佈:2020-11-24
無非就是兩種關係 \(a < b, a \le b\),考慮建圖求解。兩種關係都在 \(a, b\) 間連有向邊,若 \(a < b\) 邊權為 \(1\),否則為 \(0\)。
\(0\) 邊構成的連通分量必定取值相同,縮點後若不是 \(DAG\) 則必定無解,因為 \(1\) 出現在環中。否則就拓撲排序,求出每個連通分量的最低等級也就沒有入度的點到它的最長路,乘以它的大小即為對答案的貢獻。
#include <bits/stdc++.h> using namespace std; #define rep(i, a, b) for (int i = (a); i <= (b); i++) #define per(i, a, b) for (int i = (a); i >= (b); i--) #define fi first #define se second typedef long long LL; typedef pair <int, int> P; const int inf = 0x3f3f3f3f, mod = 1e9 + 7, N = 3e5 + 10; template <typename T> inline void rd_(T &x) { x = 0; int f = 1; char ch = getchar(); while (ch > '9' || ch < '0') { if (ch == '-') f = -1; ch = getchar(); } while (ch >= '0' && ch <= '9') x = x*10 + ch - '0', ch = getchar(); x *= f; } int n, m, d[N], cnt, tot, h[N], stk[N], siz[N], idx, dfn[N], low[N], top, scc, id[N], deg[N]; queue <int> q; vector <P> g[N]; bool vis[N]; struct Edge { int to, next, w; } e[N<<1]; void add_(int u, int v, int w) { e[++cnt] = (Edge) {v, h[u], w}; h[u] = cnt; } void dfs_(int u) { vis[u] = 1, stk[++top] = u; low[u] = dfn[u] = ++idx; for (int v, i = h[u]; i; i = e[i].next) if (!e[i].w) { v = e[i].to; if (!dfn[v]) dfs_(v), low[u] = min(low[u], low[v]); else if (vis[v]) low[u] = min(low[u], dfn[v]); } if (low[u] == dfn[u]) { scc++; int x; do { vis[x = stk[top--]] = 0; siz[scc]++, id[x] = scc; } while (x != u); } } int main() { rd_(n), rd_(m); for (int x, a, b, i = 1; i <= m; i++) { rd_(x), rd_(a), rd_(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); } rep (i, 1, n) if (!dfn[i]) dfs_(i); rep (u, 1, n) for (int v, i = h[u]; i; i = e[i].next) { v = e[i].to; if (e[i].w || id[u] != id[v]) g[id[u]].push_back(P(id[v], e[i].w)), deg[id[v]]++; } rep (i, 1, scc) if (!deg[i]) q.push(i), d[i] = 1; LL ans = 0; while (!q.empty()) { int u = q.front(); q.pop(), scc--, ans += 1ll*siz[u]*d[u]; for (int v, i = 0; i < (int) g[u].size(); i++) { v = g[u][i].fi; d[v] = max(d[v], d[u] + g[u][i].se); if (!--deg[v]) q.push(v); } } if (scc) puts("-1"); else printf("%lld\n", ans); }