제출 #829928

#제출 시각아이디문제언어결과실행 시간메모리
829928erray철인 이종 경기 (APIO18_duathlon)C++17
0 / 100
87 ms35880 KiB
#include <bits/stdc++.h> using namespace std; #ifdef DEBUG #include "/home/eagle/ioi22/debug.h" #else #define debug(...) void(37) #endif struct DSU { vector<int> link; vector<int> size; DSU(int n) { size.resize(n, 1); link.resize(n); iota(link.begin(), link.end(), 0); } int get(int v) { return link[v] = (v == link[v] ? v : get(link[v])); } bool unite(int x, int y) { x = get(x), y = get(y); if (x == y) { return false; } link[y] = x; return true; } }; int main() { ios_base::sync_with_stdio(false); cin.tie(0); int N, M; cin >> N >> M; vector<vector<int>> g(N); for (int i = 0; i < M; ++i) { int X, Y; cin >> X >> Y; --X, --Y; g[X].push_back(Y); g[Y].push_back(X); } vector<bool> vis(N); vector<int> d(N); vector<int> par(N, -1); DSU edges(N); vector<int> size(N, 1); vector<vector<int>> tree(N); vector<int> ord; function<void(int)> Dfs = [&](int v) { vis[v] = true; int back = d[v]; for (auto u : g[v]) { if (!vis[u]) { d[u] = d[v] + 1; par[u] = v; Dfs(u); size[v] += size[u]; tree[v].push_back(u); tree[u].push_back(v); } else { back = min(back, d[u]); } } int cv = v; while (d[cv] > back + 1 && edges.unite(cv, par[cv])) { cv = par[cv]; } ord.push_back(v); }; Dfs(0); vector<long long> cycle(N, 1); for (auto v : ord) { for (auto u : tree[v]) { if (u != par[v]) { cycle[v] += cycle[u] * (edges.get(u) == edges.get(v)); } } } vector<long long> tot(N); for (int i = 1; i < N; ++i) { debug(edges.get(i)); tot[edges.get(i)] += 1; } debug(cycle, tot); long long bad = 0; vector<int> ct(N); for (int i = 0; i < N; ++i) { if (i != 0) { ct[edges.get(i)] += 1; } for (auto u : tree[i]) { if (u != par[i]) { ct[edges.get(u)] += 1; } } debug(i); for (auto u : tree[i]) { long long s = size[u]; long long cyc = (ct[edges.get(u)] >= 1 ? cycle[u] : 0); if (u == par[i]) { s = N - size[i]; cyc = (ct[edges.get(i)] >= 1 ? tot[edges.get(i)] - cycle[edges.get(i)] + 1: 0); } long long dec = 1LL * s * (s - 1) - 1LL * cyc * (cyc - 1); debug(s, cyc, dec); bad += dec; } ct[edges.get(i)] = 0; for (auto u : tree[i]) { ct[edges.get(u)] = 0; } } cout << (1LL * N * (N - 1) * (N - 2) - bad) << '\n'; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...