Submission #356496

#TimeUsernameProblemLanguageResultExecution timeMemory
356496valerikkDuathlon (APIO18_duathlon)C++11
100 / 100
291 ms33772 KiB
#include <bits/stdc++.h> using namespace std; const int N = 2e5 + 7; int n, m; vector<int> g[N], g_[N]; int dep[N], low[N]; bool vis[N]; int cnt; int sub[N]; long long ans = 0; void prepare_dfs(int u, int par = -1) { vis[u] = true; low[u] = dep[u]; for (int v : g[u]) { if (v == par) continue; if (!vis[v]) { dep[v] = dep[u] + 1; prepare_dfs(v, u); low[u] = min(low[u], low[v]); } else { low[u] = min(low[u], dep[v]); } } } void add_edge(int u, int v, int c) { g_[u].push_back(c); g_[c].push_back(u); g_[v].push_back(c); g_[c].push_back(v); } void dfs(int u, int c = -1, int par = -1) { vis[u] = true; for (int v : g[u]) { if (v == par) continue; if (!vis[v]) { int c_ = c; if (dep[u] <= low[v]) c_ = ++cnt; add_edge(u, v, c_); dfs(v, c_, u); } else { if (dep[u] > dep[v]) add_edge(u, v, c); } } } int get_subtree(int u, int par = -1) { vis[u] = true; sub[u] = u <= n; for (int v : g[u]) { if (v != par) sub[u] += get_subtree(v, u); } return sub[u]; } void count_bad(int u, int total, int par = -1) { vis[u] = true; for (int v : g[u]) { if (v != par) count_bad(v, total, u); } if (u > n) { int a = g[u].size(); for (int v : g[u]) { int b = v == par ? total - sub[u] : sub[v]; ans -= (long long)(a - 1) * b * (b - 1); } } } int main() { #ifdef LOCAL freopen("input.txt", "r", stdin); #endif ios::sync_with_stdio(false); cin.tie(0); cin >> n >> m; while (m--) { int u, v; cin >> u >> v; g[u].push_back(v); g[v].push_back(u); } for (int i = 1; i <= n; ++i) vis[i] = false; for (int i = 1; i <= n; ++i) { if (!vis[i]) prepare_dfs(i); } for (int i = 1; i <= n; ++i) vis[i] = false; cnt = n; for (int i = 1; i <= n; ++i) { if (!vis[i]) dfs(i); } for (int i = 1; i <= cnt; ++i) g[i] = g_[i]; for (int i = 1; i <= cnt; ++i) { sort(g[i].begin(), g[i].end()); g[i].erase(unique(g[i].begin(), g[i].end()), g[i].end()); } for (int i = 1; i <= cnt; ++i) { if (!vis[i]) { int total = get_subtree(i); ans += (long long)total * (total - 1) * (total - 2); count_bad(i, total); } } cout << ans << endl; return 0; }
#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...