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;
struct biconnected_components{
int cnt;
vector<int> bcc;
biconnected_components(vector<vector<pair<int, int>>> &E){
int N = E.size();
vector<int> next(N, -1);
vector<int> d(N, -1);
vector<int> imos(N, 0);
for (int i = 0; i < N; i++){
if (d[i] == -1){
d[i] = 0;
dfs1(E, next, d, imos, i);
}
}
int M = 0;
for (int i = 0; i < N; i++){
M += E[i].size();
}
M /= 2;
bcc = vector<int>(M, -1);
cnt = 0;
for (int i = 0; i < N; i++){
if (d[i] == 0){
dfs2(E, d, imos, cnt, i);
}
}
}
void dfs1(vector<vector<pair<int, int>>> &E, vector<int> &next, vector<int> &d, vector<int> &imos, int v){
for (auto P : E[v]){
int w = P.second;
if (d[w] == -1){
d[w] = d[v] + 1;
next[v] = w;
dfs1(E, next, d, imos, w);
imos[v] += imos[w];
} else if (d[w] < d[v] - 1){
imos[v]++;
imos[next[w]]--;
}
}
}
void dfs2(vector<vector<pair<int, int>>> &E, vector<int> &d, vector<int> &imos, int b, int v){
for (auto P : E[v]){
int x = P.first;
int w = P.second;
if (d[w] < d[v]){
bcc[x] = b;
} else if (d[w] == d[v] + 1 && bcc[x] == -1){
if (imos[w] > 0){
bcc[x] = b;
} else {
bcc[x] = cnt;
cnt++;
}
dfs2(E, d, imos, bcc[x], w);
}
}
}
int operator [](int k){
return bcc[k];
}
int count(){
return cnt;
}
};
struct block_cut_tree{
int V;
vector<bool> cut;
vector<vector<int>> G;
vector<vector<int>> node;
block_cut_tree(vector<vector<int>> &E){
int N = E.size();
int M = 0;
vector<vector<pair<int, int>>> E2(N);
for (int i = 0; i < N; i++){
for (int j : E[i]){
if (j > i){
E2[i].push_back(make_pair(M, j));
E2[j].push_back(make_pair(M, i));
M++;
}
}
}
biconnected_components B(E2);
vector<bool> art(N, false);
int cnt = 0;
for (int i = 0; i < N; i++){
for (auto P : E2[i]){
if (B[P.first] != B[E2[i][0].first]){
art[i] = true;
}
}
if (art[i]){
cnt++;
}
}
V = cnt + B.count();
cut = vector<bool>(V, false);
G.resize(V);
node.resize(V);
int cnt2 = 0;
vector<bool> used(B.count(), false);
for (int i = 0; i < N; i++){
if (art[i]){
cut[cnt2] = true;
node[cnt2].push_back(i);
for (auto P : E2[i]){
int b = B[P.first];
if (!used[b]){
used[b] = true;
G[cnt + b].push_back(cnt2);
G[cnt2].push_back(cnt + b);
node[cnt + b].push_back(i);
}
}
for (auto P : E2[i]){
int b = B[P.first];
used[b] = false;
}
cnt2++;
} else {
if (!E2[i].empty()){
int b = B[E2[i][0].first];
node[cnt + b].push_back(i);
}
}
}
}
};
int main(){
int n, m;
cin >> n >> m;
vector<vector<int>> E(n);
for (int i = 0; i < m; i++){
int u, v;
cin >> u >> v;
u--;
v--;
E[u].push_back(v);
E[v].push_back(u);
}
block_cut_tree T(E);
vector<int> id(n, -1);
for (int i = 0; i < T.V; i++){
for (int j : T.node[i]){
if (id[j] == -1){
id[j] = i;
}
}
}
vector<int> p(T.V, -1);
vector<vector<int>> c(T.V);
queue<int> Q;
Q.push(0);
vector<int> bfs;
while (!Q.empty()){
int v = Q.front();
Q.pop();
bfs.push_back(v);
for (int w : T.G[v]){
if (w != p[v]){
p[w] = v;
c[v].push_back(w);
Q.push(w);
}
}
}
reverse(bfs.begin(), bfs.end());
vector<int> dp(T.V, 0);
for (int i = 0; i < n; i++){
dp[id[i]]++;
}
for (int v : bfs){
for (int w : c[v]){
dp[v] += dp[w];
}
}
vector<long long> sum(T.V, 0);
for (int i = 0; i < T.V; i++){
for (int w : c[i]){
sum[i] += (long long) dp[w] * (dp[w] - 1);
}
}
long long ans = (long long) n * (n - 1) * (n - 2);
for (int i = 0; i < n; i++){
if (!T.cut[id[i]]){
ans -= sum[id[i]];
ans -= (long long) (n - dp[id[i]]) * (n - dp[id[i]] - 1);
} else {
for (int j : c[id[i]]){
ans -= sum[j];
}
if (id[i] != 0){
ans -= sum[p[id[i]]];
ans += (long long) dp[id[i]] * (dp[id[i]] - 1);
ans -= (long long) (n - dp[p[id[i]]]) * (n - dp[p[id[i]]] - 1);
}
}
}
cout << ans << endl;
}
# | 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... |