이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#include <bits/stdc++.h>
using namespace std;
#ifdef DEBUG
#include "/home/eagle/ioi22/debug.h"
#else
#define debug(...) void(37)
#endif
struct DSU {
vector<int> link;
vector<int> size;
DSU(int n) {
size.resize(n, 1);
link.resize(n);
iota(link.begin(), link.end(), 0);
}
int get(int v) {
return link[v] = (v == link[v] ? v : get(link[v]));
}
bool unite(int x, int y) {
x = get(x), y = get(y);
if (x == y) {
return false;
}
link[y] = x;
return true;
}
};
int main() {
ios_base::sync_with_stdio(false);
cin.tie(0);
int N, M;
cin >> N >> M;
vector<vector<int>> g(N);
for (int i = 0; i < M; ++i) {
int X, Y;
cin >> X >> Y;
--X, --Y;
g[X].push_back(Y);
g[Y].push_back(X);
}
vector<bool> vis(N);
vector<int> d(N);
vector<int> par(N, -1);
DSU edges(N);
vector<int> size(N, 1);
vector<vector<int>> tree(N);
vector<int> ord;
function<void(int)> Dfs = [&](int v) {
vis[v] = true;
int back = d[v];
for (auto u : g[v]) {
if (!vis[u]) {
d[u] = d[v] + 1;
par[u] = v;
Dfs(u);
size[v] += size[u];
tree[v].push_back(u);
tree[u].push_back(v);
} else {
back = min(back, d[u]);
}
}
int cv = v;
while (d[cv] > back + 1 && edges.unite(cv, par[cv])) {
cv = par[cv];
}
ord.push_back(v);
};
Dfs(0);
vector<long long> cycle(N, 1);
for (auto v : ord) {
for (auto u : tree[v]) {
if (u != par[v]) {
cycle[v] += cycle[u] * (edges.get(u) == edges.get(v));
}
}
}
vector<long long> tot(N);
for (int i = 1; i < N; ++i) {
debug(edges.get(i));
tot[edges.get(i)] += 1;
}
debug(cycle, tot);
long long bad = 0;
vector<int> ct(N);
for (int i = 0; i < N; ++i) {
if (i != 0) {
ct[edges.get(i)] += 1;
}
for (auto u : tree[i]) {
if (u != par[i]) {
ct[edges.get(u)] += 1;
}
}
debug(i);
for (auto u : tree[i]) {
long long s = size[u];
long long cyc = (ct[edges.get(u)] >= 1 ? cycle[u] : 0);
if (u == par[i]) {
s = N - size[i];
cyc = (ct[edges.get(i)] >= 1 ? tot[edges.get(i)] - cycle[edges.get(i)] + 1: 0);
}
long long dec = 1LL * s * (s - 1) - 1LL * cyc * (cyc - 1);
debug(s, cyc, dec);
bad += dec;
}
ct[edges.get(i)] = 0;
for (auto u : tree[i]) {
ct[edges.get(u)] = 0;
}
}
cout << (1LL * N * (N - 1) * (N - 2) - bad) << '\n';
}
# | 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... |