제출 #321292

#제출 시각아이디문제언어결과실행 시간메모리
321292couplefire철인 이종 경기 (APIO18_duathlon)C++17
100 / 100
184 ms37732 KiB
#include <bits/stdc++.h> using namespace std; #define MAXN 200015 int low[MAXN], tin[MAXN], curTime = 0, curComp = 0; vector<int> tree[MAXN], children[MAXN]; bool isCut[MAXN]; vector<int> adj[MAXN]; bool visited[MAXN]; int n, m; int nn = 0; long long ans = 0; void tarjan(int v, int p){ visited[v] = 1; tin[v] = curTime++; low[v] = curTime-1; nn++; for(auto u : adj[v]){ if(u == p) continue; if(visited[u]){ low[v] = min(low[v], tin[u]); } else{ children[v].push_back(u); tarjan(u, v); low[v] = min(low[v], low[u]); if(low[u] >= tin[v]){ isCut[u] = 1; } } } } void ae(int a, int b){ tree[a].push_back(b); tree[b].push_back(a); } void gen(int v, int b){ if(b != 0) ae(v, b); for(auto u : children[v]){ if(isCut[u]){ curComp++; ae(v, curComp); gen(u, curComp); } else{ gen(u, b); } } } int getSiz(int v, int p){ if(v < n){ int aa = 0; for(auto u : tree[v]){ if(u == p) continue; aa += getSiz(u, v)-1; } return aa+1; } int bb = tree[v].size(); int aa = 0; for(auto u : tree[v]){ if(u == p) continue; if(tree[u].size() == 1) continue; int t = getSiz(u, v); aa += t; ans -= 1ll*(tree[v].size()-1)*t*(t-1); bb--; } // ans -= 1ll*bb*aa*(aa-1); // cout << -1ll*bb*aa*(aa-1) << endl; // ans += 1ll*bb*(tree[v].size()-bb)*(tree[v].size()-bb-1); // cout << 1ll*bb*(tree[v].size()-bb)*(tree[v].size()-bb-1) << endl; if(bb+aa != nn){ ans -= 1ll*(tree[v].size()-1)*(nn-bb-aa+1)*(nn-bb-aa); // cout << -1ll*(tree[v].size()-1)*(nn-bb-aa+1)*(nn-bb-aa) << endl; } // if(v == 11){ // cout << bb+aa << endl; // } return bb+aa; } int main(){ ios_base::sync_with_stdio(false); cin.tie(0); cin >> n >> m; for(int i = 0; i<m; i++){ int a, b; cin >> a >> b; --a; --b; adj[a].push_back(b); adj[b].push_back(a); } curComp = n-1; for(int i = 0; i<n; i++) if(!visited[i]) { nn = 0; tarjan(i, -1); ans += 1ll*nn*(nn-1)*(nn-2); gen(i, 0); getSiz(i, -1); } // for(int i = 0; i<n; i++) if(isCut[i]) cout << i+1 << endl; // for(int i = 0; i<MAXN; i++){ // if(tree[i].size()){ // cout << i+1 << endl; // for(auto j : tree[i]) cout << j+1 << " "; // cout << endl << endl;; // } // } cout << ans << endl; }
#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...