1 条题解
-
0

#include <bits/stdc++.h> #define EB emplace_back #define ad(x) (((x - 1) ^ 1) + 1) using std::cin; using std::cout; typedef long long ll; typedef std::vector <int> vector; const int N = 3054, M = 9054; struct edge { int u, v; edge (int u0 = 0, int v0 = 0) : u(u0), v(v0) {} } e[M]; int V, E, C, Es = 0; int first[N], next[M]; int cnt = 0, id[N], low[N]; int col[M], count[N]; bool banned[M]; inline void down(int &x, const int y) {x > y ? x = y : 0;} inline void addedge(int u, int v) { e[++Es] = edge(u, v), next[Es] = first[u], first[u] = Es; e[++Es] = edge(v, u), next[Es] = first[v], first[v] = Es; } void dfs(int x, int px = 0) { int i, y; id[x] = low[x] = ++cnt; for (i = first[x]; i; i = next[i]) if (!banned[i] && ~col[i]) { if (!id[y = e[i].v]) { dfs(y, x), down(low[x], low[y]); if (id[x] < low[y]) assert(!col[i]), col[i] = col[ad(i)] = C; } else if (y != px) down(low[x], id[y]); } } inline void coloring() { cnt = 0, memset(id, 0, (V + 1) << 2); for (int i = 1; i <= V; ++i) if (!id[i]) dfs(i); } namespace dsu0 { int p[N], size[N]; ll acc; inline void init(int n) {acc = 0, std::iota(p, p + (n + 1), 0), std::fill(size, size + (n + 1), 1);} int ancestor(int x) {return p[x] == x ? x : (p[x] = ancestor(p[x]));} void connect(int x, int y) { if ((x = ancestor(x)) == (y = ancestor(y))) return; acc += (ll)size[x] * size[y], size[x] > size[y] ? (p[y] = x, size[x] += size[y]) : (p[x] = y, size[y] += size[x]); } } namespace e3cc { typedef std::list <int> list; int n_e3cc = 0, p[N], deg[N], count[M]; int na = 0, absQ[M]; int nd = 0, deg2Q[N]; list li[N]; vector e3cc[N]; int ancestor(int x) {return p[x] == x ? x : (p[x] = ancestor(p[x]));} void main() { int i, j, c, u, v, x, z[3], nz; for (i = 1; i <= Es; i += 2) if (~col[i]) ++count[col[i]]; for (i = 1; i <= Es; i += 2) if (~col[i]) { ++deg[e[i].u], ++deg[e[i].v]; if (count[col[i]] == 1) absQ[na++] = i; } for (i = 1; i <= V; ++i) { li[i].EB(i), p[i] = i; if (deg[i] == 2) deg2Q[nd++] = i; } for (; ; ) if (na) { i = absQ[--na], u = ancestor(e[i].u), v = ancestor(e[i].v); if (u == v) deg[u] -= 2; else p[v] = u, deg[u] += deg[v] - 2, li[u].splice(li[u].end(), li[v]); if (deg[u] == 2) deg2Q[nd++] = u; } else if (nd) { x = deg2Q[--nd]; if (deg[x] != 2) continue; x = ancestor(x), nz = 0; for (int r : li[x]) for (i = first[r]; i; i = next[i]) if (~col[i] && ancestor(e[i].v) != x) z[nz++] = i; u = e[i = *z].v, v = e[j = z[1]].v, c = col[i]; if (p[u] == p[v]) continue; e[i].u = e[ad(i)].v = v, next[i] = first[v], first[v] = i, p[x] = p[v]; if (--count[c] == 1) absQ[na++] = i; } else break; for (i = 1; i <= V; ++i) if (!li[i].empty()) e3cc[n_e3cc++].assign(li[i].begin(), li[i].end()); } } int main() { int i, u, v; ll ans; std::ios::sync_with_stdio(false), cin.tie(NULL); cin >> V >> E; for (i = 1; i <= E; ++i) cin >> u >> v, addedge(u, v); C = -1, coloring(), C = 0; for (i = 1; i <= Es; i += 2) if (!col[i]) banned[i] = banned[i + 1] = true, col[i] = col[i + 1] = ++C, coloring(), banned[i] = banned[i + 1] = false; e3cc::main(); dsu0::init(V); for (i = 0; i < e3cc::n_e3cc; ++i) { vector &C = e3cc::e3cc[i]; for (int x : C) dsu0::connect(x, C.back()); } ans = dsu0::acc; for (i = 1; i <= Es; i += 2) if (~col[i]) dsu0::connect(e[i].u, e[i].v); ans += dsu0::acc; for (i = 1; i <= Es; i += 2) if (!~col[i]) dsu0::connect(e[i].u, e[i].v); cout << ans + dsu0::acc << '\n'; return 0; }
- 1
信息
- ID
- 6100
- 时间
- 7000ms
- 内存
- 128MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者