This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include <bits/stdc++.h>
using namespace std;
#define N 200000
vector<unsigned> g[N], bccg[N];
unsigned y[N], l[N], subtree_size[N], s[N];
bitset<N> visited;
size_t n, m, t = 0, n_bcc;
unsigned build_bcc_tree(unsigned u, unsigned p = -1, unsigned i = 0)
{
y[u] = l[u] = i++;
visited[u] = 1;
s[t++] = u;
for (unsigned const &v : g[u])
{
if (!visited[v])
{
i = build_bcc_tree(v, u, i);
l[u] = min(l[u], l[v]);
if (l[v] >= y[u])
{
// Collect all nodes in the BCC of u and v. u is an articulation
// point, so leave it in the stack.
bccg[u].push_back(n_bcc);
while (s[t] != v)
bccg[n_bcc].push_back(s[--t]);
n_bcc++;
}
}
else if (v != p)
l[u] = min(l[u], y[v]);
}
return i;
}
// The BCC graph is bipartite with BCCs in one partition and original nodes in
// the other.
uint64_t get_bad_triples(unsigned u, uint64_t c, unsigned p = -1)
{
uint64_t ans = 0;
subtree_size[u] = u < n;
for (unsigned const &v : bccg[u])
{
if (v != p)
{
ans += get_bad_triples(v, c, u);
subtree_size[u] += subtree_size[v];
if (v < n)
ans += bccg[u].size() * subtree_size[v] * (subtree_size[v] - 1);
}
}
if (u >= n) // Add the contribution with the pair (s, f) outside u's subtree.
ans += bccg[u].size() * (c - subtree_size[u]) * (c - subtree_size[u] - 1);
return ans;
}
int main()
{
scanf("%zu %zu", &n, &m);
n_bcc = n;
for (size_t i = 0; i < m; i++)
{
unsigned u, v;
scanf("%u %u", &u, &v);
g[u - 1].push_back(v - 1);
g[v - 1].push_back(u - 1);
}
unsigned long long ans = 0;
for (size_t i = 0; i < n; i++)
if (!visited[i])
{
uint64_t c = build_bcc_tree(i);
ans -= get_bad_triples(i, c);
ans += c * (c - 1) * (c - 2);
}
printf("%llu\n", ans);
}
Compilation message (stderr)
count_triplets.cpp: In function 'int main()':
count_triplets.cpp:65:10: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
65 | scanf("%zu %zu", &n, &m);
| ~~~~~^~~~~~~~~~~~~~~~~~~
count_triplets.cpp:71:14: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
71 | scanf("%u %u", &u, &v);
| ~~~~~^~~~~~~~~~~~~~~~~
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |