Submission #1213330

#TimeUsernameProblemLanguageResultExecution timeMemory
1213330spike1236Duathlon (APIO18_duathlon)C++20
0 / 100
110 ms28436 KiB
#include <bits/stdc++.h> using namespace std; static const int MOD = 1000000007; int N, M; vector<vector<int>> G; vector<int> disc, low, stk; vector<bool> inStack; int timerTarjan; vector<vector<int>> blocks; vector<vector<int>> Tadj; vector<long long> weightT; vector<long long> subtree_size; vector<bool> visitedT; long long totalBad = 0; void tarjanDFS(int u, int parent) { disc[u] = low[u] = ++timerTarjan; stk.push_back(u); inStack[u] = true; for (int v : G[u]) { if (v == parent) continue; if (!disc[v]) { tarjanDFS(v, u); low[u] = min(low[u], low[v]); if (low[v] >= disc[u]) { blocks.emplace_back(); while (true) { int x = stk.back(); stk.pop_back(); inStack[x] = false; blocks.back().push_back(x); if (x == v) break; } blocks.back().push_back(u); } } else if (inStack[v]) { low[u] = min(low[u], disc[v]); } } } void dfsTree(int u, int parent, long long &totCircle) { visitedT[u] = true; subtree_size[u] = (u <= N ? 1LL : 0LL); for (int v : Tadj[u]) { if (v == parent) continue; if (!visitedT[v]) { dfsTree(v, u, totCircle); subtree_size[u] += subtree_size[v]; long long a = subtree_size[v]; long long b = (totCircle - subtree_size[v]); long long contrib = ( ( (weightT[u] % MOD + MOD ) % MOD ) * (a % MOD) % MOD * (b % MOD) ) % MOD; contrib = (2LL * contrib) % MOD; totalBad = (totalBad + contrib) % MOD; } } } int main(){ ios::sync_with_stdio(false); cin.tie(nullptr); cin >> N >> M; G.assign(N+1, {}); for (int i = 0, u, v; i < M; i++){ cin >> u >> v; G[u].push_back(v); G[v].push_back(u); } disc.assign(N+1, 0); low.assign(N+1, 0); inStack.assign(N+1, false); timerTarjan = 0; for (int u = 1; u <= N; u++){ if (!disc[u]) { tarjanDFS(u, 0); if (!stk.empty()) { blocks.emplace_back(); while (!stk.empty()) { int x = stk.back(); stk.pop_back(); inStack[x] = false; blocks.back().push_back(x); } } } } int B = (int)blocks.size(); Tadj.assign(N + B + 1, {}); weightT.assign(N + B + 1, 0LL); for (int u = 1; u <= N; u++){ weightT[u] = -1; } for (int i = 0; i < B; i++){ int bnode = N + 1 + i; long long blockSize = (long long)blocks[i].size(); weightT[bnode] = (blockSize - 2LL); for (int v : blocks[i]) { Tadj[bnode].push_back(v); Tadj[v].push_back(bnode); } } int totalNodesT = N + B; visitedT.assign(totalNodesT+1, false); subtree_size.assign(totalNodesT+1, 0LL); for (int u = 1; u <= totalNodesT; u++){ if (!visitedT[u] && ((u <= N && weightT[u] == -1) || (u > N && weightT[u] != 0))) { long long totCircle = 0; queue<int>q; vector<int>componentNodes; visitedT[u] = true; q.push(u); if (u <= N && weightT[u] == -1) totCircle++; componentNodes.push_back(u); while(!q.empty()){ int x = q.front(); q.pop(); for (int v : Tadj[x]) { if (!visitedT[v]) { visitedT[v] = true; q.push(v); componentNodes.push_back(v); if (v <= N && weightT[v] == -1) { totCircle++; } } } } for (int x : componentNodes) { visitedT[x] = false; } dfsTree(u, 0, totCircle); for (int x : componentNodes) { visitedT[x] = true; } } } long long totalOrdered = ( (long long)N * (N - 1) ) % MOD; totalOrdered = ( totalOrdered * (N - 2) ) % MOD; long long answer = ( (totalOrdered - totalBad) % MOD + MOD ) % MOD; 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...