Submission #1213345

#TimeUsernameProblemLanguageResultExecution timeMemory
1213345spike1236Duathlon (APIO18_duathlon)C++20
0 / 100
98 ms45872 KiB
#include <bits/stdc++.h> using namespace std; int n, m; vector<vector<int>> adj; vector<int> disc, low; vector<bool> is_art; int time_dfs; vector<pair<int,int>> edgeStack; vector<vector<int>> bcc_list; vector<vector<int>> vertex_to_bcc; vector<int> in_comp; void tarjan(int u, int parent) { disc[u] = low[u] = ++time_dfs; int child_count = 0; for (int v : adj[u]) { if (disc[v] == 0) { child_count++; edgeStack.emplace_back(u, v); tarjan(v, u); low[u] = min(low[u], low[v]); if (parent != -1 && low[v] >= disc[u]) is_art[u] = true; if (parent == -1 && child_count > 1) is_art[u] = true; if (low[v] >= disc[u]) { int id = bcc_list.size(); vector<int> comp; while (true) { auto e = edgeStack.back(); edgeStack.pop_back(); int x = e.first, y = e.second; if (in_comp[x] != id + 1) { in_comp[x] = id + 1; comp.push_back(x); } if (in_comp[y] != id + 1) { in_comp[y] = id + 1; comp.push_back(y); } if ((x == u && y == v) || (x == v && y == u)) break; } bcc_list.push_back(comp); for (int w : comp) vertex_to_bcc[w].push_back(id); } } else if (v != parent && disc[v] < disc[u]) { low[u] = min(low[u], disc[v]); edgeStack.emplace_back(u, v); } } } int main() { ios::sync_with_stdio(false); cin.tie(NULL); cin >> n >> m; adj.assign(n + 1, {}); for (int i = 0; i < m; i++) { int u, v; cin >> u >> v; adj[u].push_back(v); adj[v].push_back(u); } disc.assign(n + 1, 0); low.assign(n + 1, 0); is_art.assign(n + 1, false); time_dfs = 0; vertex_to_bcc.assign(n + 1, {}); in_comp.assign(n + 1, 0); for (int i = 1; i <= n; i++) { if (disc[i] == 0) { tarjan(i, -1); if (!edgeStack.empty()) { int id = bcc_list.size(); vector<int> comp; while (!edgeStack.empty()) { auto e = edgeStack.back(); edgeStack.pop_back(); int x = e.first, y = e.second; if (in_comp[x] != id + 1) { in_comp[x] = id + 1; comp.push_back(x); } if (in_comp[y] != id + 1) { in_comp[y] = id + 1; comp.push_back(y); } } bcc_list.push_back(comp); for (int w : comp) vertex_to_bcc[w].push_back(id); } } } int num_bcc = bcc_list.size(); int totalNodes = n + num_bcc; vector<vector<int>> bct_adj(totalNodes + 1); vector<long long> weight(totalNodes + 1, 0); vector<int> B_sz(num_bcc); for (int bcc_id = 0; bcc_id < num_bcc; bcc_id++) { B_sz[bcc_id] = bcc_list[bcc_id].size(); } for (int v = 1; v <= n; v++) { if (is_art[v]) weight[v] = 1; } for (int bcc_id = 0; bcc_id < num_bcc; bcc_id++) { int node_id = n + 1 + bcc_id; int art_count = 0; for (int v : bcc_list[bcc_id]) { if (is_art[v]) { art_count++; bct_adj[node_id].push_back(v); bct_adj[v].push_back(node_id); } } weight[node_id] = B_sz[bcc_id] - art_count; } vector<int> parent(totalNodes + 1, -1); vector<bool> visited_bct(totalNodes + 1, false); vector<long long> size_subtree(totalNodes + 1, 0); vector<long long> comp_total(totalNodes + 1, 0); for (int start = 1; start <= totalNodes; start++) { if (start <= n && !is_art[start]) continue; if (visited_bct[start]) continue; vector<int> comp_nodes; stack<pair<int,int>> stk; parent[start] = 0; visited_bct[start] = true; comp_nodes.push_back(start); stk.push({start, 0}); while (!stk.empty()) { int node = stk.top().first; int &idx = stk.top().second; if (idx < (int)bct_adj[node].size()) { int nei = bct_adj[node][idx]; idx++; if (!visited_bct[nei]) { visited_bct[nei] = true; parent[nei] = node; comp_nodes.push_back(nei); stk.push({nei, 0}); } } else { long long total_w = weight[node]; for (int w : bct_adj[node]) { if (parent[w] == node) total_w += size_subtree[w]; } size_subtree[node] = total_w; stk.pop(); } } long long totW = size_subtree[start]; for (int u : comp_nodes) comp_total[u] = totW; } long long answer = 0; for (int c = 1; c <= n; c++) { if (!is_art[c]) { int bcc_id = vertex_to_bcc[c][0]; int bnode = n + 1 + bcc_id; long long D0 = (long long)B_sz[bcc_id] - 1; long long L0 = 0, sum_l2 = 0; for (int a : bct_adj[bnode]) { long long comp_ab; if (parent[a] == bnode) { comp_ab = size_subtree[a]; } else { comp_ab = comp_total[bnode] - size_subtree[bnode]; } long long li = comp_ab - 1; L0 += li; sum_l2 += li * li; } long long term = 0; if (D0 >= 2) term += D0 * (D0 - 1); term += (L0 * L0 - sum_l2); term += 2LL * (D0 - 1) * L0; answer += term; } else { long long sum_S = 0, sum_S_sq = 0; long long sum_intra = 0; for (int bnode : bct_adj[c]) { long long S_j; if (parent[bnode] == c) { S_j = size_subtree[bnode]; } else { S_j = comp_total[c] - size_subtree[c]; } sum_S += S_j; sum_S_sq += S_j * S_j; int bcc_id = bnode - n - 1; long long D_j = (long long)B_sz[bcc_id] - 1; long long L_j = 0, sum_l2 = 0; for (int a : bct_adj[bnode]) { if (a == c) continue; long long comp_ab; if (parent[a] == bnode) { comp_ab = size_subtree[a]; } else { comp_ab = comp_total[bnode] - size_subtree[bnode]; } long long l_i = comp_ab - 1; L_j += l_i; sum_l2 += l_i * l_i; } long long intra = 0; if (D_j >= 2) intra += D_j * (D_j - 1); intra += (L_j * L_j - sum_l2); intra += 2LL * (D_j - 1) * L_j; sum_intra += intra; } long long cross_pairs = sum_S * sum_S - sum_S_sq; answer += cross_pairs + sum_intra; } } cout << answer << "\n"; 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...