This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
/**
* author : Lăng Trọng Đạt
* created: 09-06-2024
**/
#include <bits/stdc++.h>
using namespace std;
#ifndef LANG_DAT
#define db(...) ;
#endif // LANG_DAT
#define int long long
#define mp make_pair
#define f first
#define se second
#define pb push_back
#define all(v) (v).begin(), (v).end()
using pii = pair<int, int>;
using vi = vector<int>;
#define FOR(i, a, b) for (int (i) = a; (i) <= (b); i++)
void mx(int& a, int b) { if (b > a) a = b; }
void mi(int& a, int b) { if (b < a) a = b; }
#define si(x) (int)(x.size())
const int INF = 1e18;
const int MOD = 1e9 + 7;
/*
1. Init (input graph)
2. Finding all cut vertex
3. Transform graph into block-cut tree
4. Calculate subsize of each node (in block-cut tree)
*/
const int MAXN = 2e5 + 5;
int g[MAXN];
int n, m, a, b;
vi adj[MAXN];
int timer = 1;
bool ap[MAXN];
int id[MAXN], low[MAXN];
int bad = 0;
vi path;
vi bcc_adj[MAXN];
int bcc_num = 1;
int N = 0;
void dfs(int v, int prv) {
N++;
path.pb(v);
id[v] = low[v] = timer++;
for (int u : adj[v]) {
if (u == prv) continue;
if (id[u]) mi(low[v], id[u]);
else {
dfs(u, v);
mi(low[v], low[u]);
if (id[v] <= low[u]) {
db(v, u, low[u], id[v], bcc_num)
bcc_adj[v].pb(bcc_num + n);
while (bcc_adj[bcc_num + n].empty() || bcc_adj[bcc_num + n].back() != u) {
bcc_adj[bcc_num + n].pb(path.back());
path.pop_back();
}
bcc_num++;
}
}
}
}
int ans = 0;
int sz[MAXN];
void dfs2(int v, int prv) {
if (v <= n) sz[v] = 1;
for (int u : bcc_adj[v]) {
// if (u == prv) continue;
dfs2(u, v);
sz[v] += sz[u];
if (v > n) ans -= si(bcc_adj[v]) * sz[u] * (sz[u] - 1); // v is change
}
if (v > n) ans -= si(bcc_adj[v]) * (N - sz[v]) * (N - sz[v] - 1);
db(ans, v, sz[v])
}
void init() {
cin >> n >> m;
FOR(i, 1, m) {
cin >> a >> b;
adj[a].pb(b);
adj[b].pb(a);
}
FOR(i, 1, n) {
if (!id[i]) {
N = 0;
dfs(i, -1);
ans += N * (N - 1) * (N - 2);
db(i, ans, N)
dfs2(i, -1);
}
}
// FOR(i, 1, n + bcc_num) {
// for (int u : bcc_adj[i]) {
// cout << i << " " << u << "\n";
// }
// }
}
int32_t main() {
cin.tie(0)->sync_with_stdio(0);
if (fopen("hi.inp", "r")) {
freopen("hi.inp", "r", stdin);
// freopen("hi.out", "w", stdout);
}
init();
cout << ans;
}
Compilation message (stderr)
count_triplets.cpp: In function 'void init()':
count_triplets.cpp:18:31: warning: unnecessary parentheses in declaration of 'i' [-Wparentheses]
18 | #define FOR(i, a, b) for (int (i) = a; (i) <= (b); i++)
| ^
count_triplets.cpp:84:5: note: in expansion of macro 'FOR'
84 | FOR(i, 1, m) {
| ^~~
count_triplets.cpp:18:31: warning: unnecessary parentheses in declaration of 'i' [-Wparentheses]
18 | #define FOR(i, a, b) for (int (i) = a; (i) <= (b); i++)
| ^
count_triplets.cpp:89:5: note: in expansion of macro 'FOR'
89 | FOR(i, 1, n) {
| ^~~
count_triplets.cpp: In function 'int32_t main()':
count_triplets.cpp:108:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
108 | freopen("hi.inp", "r", stdin);
| ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~
# | 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... |