Submission #57775

#TimeUsernameProblemLanguageResultExecution timeMemory
57775CrownDuathlon (APIO18_duathlon)C++14
100 / 100
514 ms98968 KiB
#include <bits/stdc++.h> using namespace std; #define X first #define Y second #define pb push_back typedef long long ll; typedef pair<int, int> ii; const int maxn = 1e5+5; const int maxm = 2e5+5; int n, m; vector< ii > adj[maxn]; int U[maxm], V[maxm]; int num[maxn], low[maxn]; int now = 1; bool instack[maxm]; stack<int> s; int compno; int col[maxm]; vector<int> tree[2*(maxn+maxm)]; int cnt[2*(maxn+maxm)]; bool use[maxn+maxm]; ll pong[maxn+maxm]; void tarjan(int u, int p) { num[u] = low[u] = now; now++; for(auto earn : adj[u]) { int v = earn.X, id = earn.Y; if(!num[v]) { if(!instack[id]) { s.push(id); instack[id] = true; } tarjan(v, u); low[u] = min(low[u], low[v]); if(low[v]>= num[u]) { // u is an articulation point compno++; while(!s.empty()) { int x = s.top(); s.pop(); col[x] = compno; if(x == id) break; } } } else if(v != p) { if(!instack[id]) { s.push(id); instack[id] = true; } low[u] = min(low[u], num[v]); } } } ll res; ll sel3(int x){ return 1LL*x*(x-1)*(x-2); } ll sel2(int x){ return 1LL*x*(x-1); } void dfs(int u, int p) { use[u] = true; cnt[u] = u<=n; for(auto v : tree[u]) { if(v == p) continue; dfs(v, u); cnt[u] += cnt[v]; if(u> n) pong[u] += sel2(cnt[v]); } } ll total = 0; void solve(int u, int p) { for(auto v : tree[u]) { if(v == p) continue; solve(v, u); } if(u> n) return; for(auto v : tree[u]) { if(v != p) res -= pong[v]; else res -= pong[v] - sel2(cnt[u]) + sel2(total-cnt[v]); } } int main() { scanf("%d %d", &n, &m); for(int i = 1; i<= m; i++) { int u, v; scanf("%d %d", &u, &v); U[i] = u; V[i] = v; adj[u].pb(ii(v, i)); adj[v].pb(ii(u, i)); } for(int i = 1; i<= n; i++) { if(num[i]) continue; tarjan(i, 0); if(!s.empty()) { compno++; while(!s.empty()) { int x = s.top(); s.pop(); col[x] = compno; } } } for(int i = 1; i<= m; i++) { int x = col[i]; int u = U[i], v = V[i]; tree[u].pb(n+x); tree[n+x].pb(u); tree[v].pb(n+x); tree[n+x].pb(v); } for(int i = 1; i<= compno+n; i++) { sort(tree[i].begin(), tree[i].end()); tree[i].resize(unique(tree[i].begin(), tree[i].end())-tree[i].begin()); } for(int i = 1; i<= n; i++) { if(use[i]) continue; dfs(i, 0); total = cnt[i]; res += sel3(total); solve(i, 0); } printf("%lld\n", res); }

Compilation message (stderr)

count_triplets.cpp: In function 'int main()':
count_triplets.cpp:105:7: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
  scanf("%d %d", &n, &m);
  ~~~~~^~~~~~~~~~~~~~~~~
count_triplets.cpp:108:18: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
   int u, v; scanf("%d %d", &u, &v);
             ~~~~~^~~~~~~~~~~~~~~~~
#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...