Submission #57767

#TimeUsernameProblemLanguageResultExecution timeMemory
57767CrownDuathlon (APIO18_duathlon)C++14
10 / 100
373 ms40624 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)]; 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; void dfs(int u, int p) { cnt[u] = u>compno; for(auto v : tree[u]) { if(v == p) continue; dfs(v, u); cnt[u] += cnt[v]; } } void solve(int u, int p, int par_cnt) { //printf("%d (%d)\n", u, par_cnt); if(u> compno) { ll tot = 0; ll sq = 0; for(auto v : tree[u]) { if(v == p) continue; tot += cnt[v]; sq += cnt[v]*cnt[v]; } res += tot*tot-sq; } else { ll tot = 0; ll sq = 0; vector<int> ne; for(auto v : tree[u]) { if(v == p) continue; ne.pb(cnt[v]); tot += cnt[v]; sq += cnt[v]*cnt[v]; } //printf("tot is %lld sq is %lld\n", tot, sq); if(par_cnt) { tot += par_cnt; sq += 1LL*par_cnt*par_cnt; } for(auto x : ne) { res += (tot-1)*(tot-1) - (sq - (2*x - 1) ); } } //printf("res is now %lld\n", res); int tot = u> compno; for(auto v : tree[u]) { if(v == p) continue; tot += cnt[v]; } for(auto v : tree[u]) { if(v == p) continue; solve(v, u, par_cnt+tot-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[compno+u].pb(x); tree[x].pb(compno+u); tree[compno+v].pb(x); tree[x].pb(compno+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<= compno+n; i++) { if(cnt[i]) continue; dfs(i, 0); solve(i, 0, 0); } printf("%lld\n", res); }

Compilation message (stderr)

count_triplets.cpp: In function 'int main()':
count_triplets.cpp:132: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:135: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...