제출 #1190270

#제출 시각아이디문제언어결과실행 시간메모리
1190270omsincoconut철인 이종 경기 (APIO18_duathlon)C++17
31 / 100
139 ms36948 KiB
/* Do 2-edge connectivity => Get condensation tree If s, c, f all in different components Imagine the condensation tree having the vertices' weights = number of vertex in that component Fix the position of c, it is easy to calculate the number of possible (s, f) If s, c, f all in same components For each component with n vertices, add n(n-1)(n-2) If s, c in same component but f in different We can have any (s, c, f) except if s is on the path fron c to f. It is easier to subtract out that case. */ #include <bits/stdc++.h> using namespace std; typedef long long ll; const int MAXN = 1e5+5; ll n, m; vector<int> edge[MAXN]; vector<pair<int, int>> edge_list; int p[MAXN], tin[MAXN], low[MAXN]; void dfs(int u) { static int ct = 1; low[u] = tin[u] = ct++; for (int v : edge[u]) { if (tin[v] == -1) { p[v] = u; dfs(v); } if (p[u] != v || upper_bound(edge_list.begin(), edge_list.end(), make_pair(u, v)) - lower_bound(edge_list.begin(), edge_list.end(), make_pair(u, v)) >= 2) low[u] = min(low[v], low[u]); } } vector<int> lowlist; vector<int> comp[MAXN]; vector<int> treeedge[MAXN]; ll dp[MAXN]; vector<int> treechild[MAXN]; int treep[MAXN]; int cc = 1; int treecomp[MAXN]; ll treecompsz[MAXN]; void treedfs(int u) { dp[u] = comp[u].size(); treecomp[u] = cc; for (int v : treeedge[u]) { if (dp[v] != -1) continue; treechild[u].push_back(v); treep[v] = u; treedfs(v); dp[u] += dp[v]; } } vector<pair<int, int>> temptemp; vector<int> tempedge[MAXN]; int main() { ios_base::sync_with_stdio(false); cin.tie(NULL); cin >> n >> m; for (int i = 1; i <= m; i++) { int u, v; cin >> u >> v; edge[u].push_back(v); edge[v].push_back(u); edge_list.emplace_back(u, v); edge_list.emplace_back(v, u); } sort(edge_list.begin(), edge_list.end()); fill(tin, tin+n+1, -1); fill(p, p+n+1, -1); for (int i = 1; i <= n; i++) { if (p[i] == -1) { p[i] = i; dfs(i); } } for (int u = 1; u <= n; u++) { if (tin[u] > low[u]) continue; for (int v : edge[u]) { if (tin[v] < tin[u]) { temptemp.emplace_back(u, v); temptemp.emplace_back(v, u); } } } sort(temptemp.begin(), temptemp.end()); for (int u = 1; u <= n; u++) { for (int v : edge[u]) { if (!binary_search(temptemp.begin(), temptemp.end(), make_pair(u, v))) { tempedge[u].push_back(v); } } } fill(low, low+n+1, -1); int llow = 1; for (int i = 1; i <= n; i++) { if (low[i] != -1) continue; queue<int> dt; dt.push(i); while (!dt.empty()) { int u = dt.front(); dt.pop(); if (low[u] != -1) continue; low[u] = llow; for (int v : tempedge[u]) dt.push(v); } llow++; } for (int i = 1; i <= n; i++) { lowlist.push_back(low[i]); comp[low[i]].push_back(i); } sort(lowlist.begin(), lowlist.end()); lowlist.resize(unique(lowlist.begin(), lowlist.end()) - lowlist.begin()); for (int u = 1; u <= n; u++) { for (int v : edge[u]) { if (low[u] != low[v]) { treeedge[low[u]].push_back(low[v]); } } } fill(dp, dp+n+1, -1); for (int i : lowlist) { if (dp[i] == -1) { treep[i] = i; treedfs(i); treecompsz[cc] = dp[i]; cc++; } } // Case 1 ll case1 = 0; for (int i : lowlist) { ll sm = 0, nans = 0; for (int j : treechild[i]) { nans += dp[j]*sm; sm += dp[j]; } nans += (treecompsz[treecomp[i]]-dp[i])*sm; case1 += nans*(ll)(comp[i].size())*2; } // Case 2 ll case2 = 0; for (int i : lowlist) { ll sz = comp[i].size(); case2 += sz*(sz-1)*(sz-2); } // Case 3 ll case3 = 0; for (int i : lowlist) { ll sz = comp[i].size(); for (int j : treechild[i]) { case3 += (sz-1)*(sz-1)*dp[j]; } case3 += (sz-1)*(sz-1)*(treecompsz[treecomp[i]]-dp[i]); } cout << case1 + case2 + 2*case3; return 0; } /* 4 4 1 2 2 3 3 4 4 2 */
#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...