Submission #1213310

#TimeUsernameProblemLanguageResultExecution timeMemory
1213310spike1236Duathlon (APIO18_duathlon)C++20
0 / 100
65 ms31676 KiB
#include <bits/stdc++.h> using namespace std; static const int MOD = 1000000007; int N, M; vector<vector<int>> graphAdj; vector<int> disc, low, parentHT; vector<bool> isCut; int timerHT; stack<pair<int,int>> edgeStack; vector<vector<int>> blocks; void dfsHT(int u) { disc[u] = low[u] = ++timerHT; int childCount = 0; for (int v : graphAdj[u]) { if (disc[v] == 0) { parentHT[v] = u; childCount++; edgeStack.push({u, v}); dfsHT(v); low[u] = min(low[u], low[v]); bool rootCase = (parentHT[u] == 0 && childCount > 1); bool nonRootCase = (parentHT[u] != 0 && low[v] >= disc[u]); if (rootCase || nonRootCase) { isCut[u] = true; vector<int> thisBlock; while (true) { auto e = edgeStack.top(); edgeStack.pop(); thisBlock.push_back(e.first); thisBlock.push_back(e.second); if (e.first == u && e.second == v) break; } sort(thisBlock.begin(), thisBlock.end()); thisBlock.erase(unique(thisBlock.begin(), thisBlock.end()), thisBlock.end()); blocks.push_back(move(thisBlock)); } } else if (v != parentHT[u] && disc[v] < disc[u]) { low[u] = min(low[u], disc[v]); edgeStack.push({u, v}); } } } void findBiconnected() { disc .assign(N+1, 0); low .assign(N+1, 0); parentHT .assign(N+1, 0); isCut .assign(N+1, false); timerHT = 0; for (int u = 1; u <= N; u++) { if (disc[u] == 0) { dfsHT(u); if (!edgeStack.empty()) { vector<int> thisBlock; while (!edgeStack.empty()) { auto e = edgeStack.top(); edgeStack.pop(); thisBlock.push_back(e.first); thisBlock.push_back(e.second); } sort(thisBlock.begin(), thisBlock.end()); thisBlock.erase(unique(thisBlock.begin(), thisBlock.end()), thisBlock.end()); blocks.push_back(move(thisBlock)); } } } } int main(){ ios::sync_with_stdio(false); cin.tie(nullptr); cin >> N >> M; graphAdj.assign(N+1, {}); for(int i = 0; i < M; i++){ int u,v; cin >> u >> v; graphAdj[u].push_back(v); graphAdj[v].push_back(u); } findBiconnected(); int B = (int)blocks.size(); int Tnodes = B + N + 1; vector<vector<int>> Tadj(Tnodes); for(int i = 0; i < B; i++){ for(int v : blocks[i]) { if (isCut[v]) { int blockNode = i+1; int cutNode = B + v; Tadj[blockNode].push_back(cutNode); Tadj[cutNode].push_back(blockNode); } } } vector<long long> weight(Tnodes, 0LL); for(int i = 1; i <= B; i++){ long long w = 0; for(int v : blocks[i-1]) { if (!isCut[v]) { w++; } } weight[i] = w; } for(int v = 1; v <= N; v++){ if (isCut[v]) { weight[B + v] = 1; } } int root; if (B >= 1) { root = 1; } else { root = 1; } vector<int> parentT(Tnodes, 0); vector<long long> subtree_sz(Tnodes, 0LL); struct Item { int u, p, idx; }; vector<Item> stk; stk.reserve(Tnodes * 2); stk.push_back({root, 0, 0}); parentT[root] = 0; while(!stk.empty()) { Item &it = stk.back(); int u = it.u; int p = it.p; int &idx = it.idx; if (idx < (int)Tadj[u].size()) { int v = Tadj[u][idx++]; if (v == p) continue; parentT[v] = u; stk.push_back({v, u, 0}); } else { long long sumw = weight[u]; for (int v : Tadj[u]) { if (parentT[v] == u) { sumw += subtree_sz[v]; } } subtree_sz[u] = sumw; stk.pop_back(); } } long long totalWeight = 0; for (int u = 1; u < Tnodes; u++) { totalWeight += weight[u]; } long long totalBad = 0; for (int v = 1; v <= N; v++) { if (!isCut[v]) continue; int cutNode = B + v; long long szCutNode = subtree_sz[cutNode]; for (int blockNode : Tadj[cutNode]) { long long ai; if (parentT[blockNode] == cutNode) { ai = subtree_sz[blockNode]; } else { ai = totalWeight - szCutNode; } long long bi = (long long)blocks[blockNode - 1].size(); long long term = ( (bi - 1) % MOD ); long long x = ( (N - ai) % MOD + MOD ) % MOD; long long y = ( (N - ai - 1) % MOD + MOD ) % MOD; term = ( term * x ) % MOD; term = ( term * y ) % MOD; totalBad = ( totalBad + term ) % MOD; } } 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...