제출 #229630

#제출 시각아이디문제언어결과실행 시간메모리
229630lyc철인 이종 경기 (APIO18_duathlon)C++14
10 / 100
112 ms24824 KiB
#include <bits/stdc++.h> using namespace std; #define TRACE(x) cerr << #x << " :: " << x << endl #define _ << " " << #define SZ(x) (int)(x).size() #define ALL(x) (x).begin(),(x).end() #define FOR(i,a,b) for(int i=(a);i<=(b);++i) #define RFOR(i,a,b) for (int i=(a);i>=(b);--i) const int MX_N = 1e5+5; int N, M; vector<int> al[MX_N]; namespace BCT { int pre[MX_N], low[MX_N], cnt, root, rootChildren; vector<int> stk; int comp[MX_N], sz[MX_N]; int nap, nv; vector<int> tree[MX_N]; void dfs(int u, int p) { pre[u] = low[u] = ++cnt; for (int v : al[u]) if (v != p) { if (pre[v] == -1) { dfs(v,u); if (u == root) ++rootChildren; else if (comp[u] == -1 && low[v] >= pre[u]) comp[u] = ++nv, sz[nv] = 1; low[u] = min(low[u],low[v]); } else { low[u] = min(low[u],pre[v]); } } } void addEdge(int u, int v) { tree[u].push_back(v); tree[v].push_back(u); } void decomp(int u, int p) { pre[u] = ++cnt; stk.push_back(u); for (int v : al[u]) if (v != p) { if (pre[v] == -1) { int st = stk.back(); decomp(v,u); if (comp[u] != -1 && low[v] >= pre[u]) { sz[++nv] = 1; addEdge(comp[u],nv); while (stk.back() != st) { int& w = stk.back(); stk.pop_back(); ++sz[nv]; if (comp[w] == -1) comp[w] = nv; else addEdge(comp[w],nv); } } } } } void run() { fill_n(comp,N+1,-1); nv = 0; fill_n(pre,N+1,-1); cnt = 0; FOR(u,1,N) if (pre[u] == -1) { root = u, rootChildren = 0; dfs(u,0); if (rootChildren > 1) comp[u] = ++nv, sz[nv] = 1; } nap = nv; fill_n(pre,N+1,-1); cnt = 0; FOR(u,1,N) if (pre[u] == -1) { stk.clear(); decomp(u,0); if (comp[u] == -1) { sz[++nv] = 0; while (!stk.empty()) { int& w = stk.back(); stk.pop_back(); ++sz[nv]; if (comp[w] == -1) comp[w] = nv; else addEdge(comp[w],nv); } } } } void dbg() { FOR(i,1,N){ TRACE(i _ pre[i] _ low[i] _ comp[i]); } TRACE(nv); cout << "APs: "; FOR(i,1,N){ if (comp[i] <= nap) cout << i << ' '; } cout << endl; FOR(i,1,nv){ cout << i << " (" << sz[i] << "): "; for(int v : tree[i]) { cout << v << ' '; } cout << endl; } } long long ans; int sub[MX_N]; void precomp(int u, int p) { sub[u] = sz[u]; for (int v : tree[u]) if (v != p) { precomp(v,u); sub[u] += sub[v]; --sub[u]; } //TRACE(u _ sz[u] _ u _ sub[u]); } void trav(int u, int p, int all) { for (int v : tree[u]) if (v != p) { trav(v,u,all); } if (u <= nap) { //if (p != 0) TRACE(u _ 2LL * (all-sub[u]) * (sub[u]-1)); if (p != 0) ans += 2LL * (all-sub[u]) * (sub[u]-1); for (int v : tree[u]) if (v != p) { ans += (sub[v]-1) * (sub[u]-sub[v]); } } else { if (sz[u] >= 2) { //TRACE(u _ (all-sub[u]) _ (sz[u]-2) _ (sz[u]-SZ(tree[u]))); if (p != 0) ans += 2LL * (all-sub[u]) * (sz[u]-2) * (sz[u]-SZ(tree[u])); for (int v : tree[u]) if (v != p) { ans += (sub[v]-1) * (sz[u]-2) * (sz[u]-SZ(tree[u])); } if (sz[u] >= 3) ans += sz[u] * (sz[u]-1) * (sz[u]-2); } } } long long solve() { ans = 0; fill_n(sub,N+1,-1); FOR(i,1,nv) if (sub[i] == -1) { precomp(i,0); trav(i,0,sub[i]); } return ans; } }; int main() { ios::sync_with_stdio(false); cin.tie(0); cin >> N >> M; FOR(i,1,M){ int U, V; cin >> U >> V; al[U].push_back(V); al[V].push_back(U); } BCT::run(); //BCT::dbg(); cout << BCT::solve() << '\n'; }
#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...