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 MAXN 200015
int low[MAXN], tin[MAXN], curTime = 0, curComp = 0;
vector<int> tree[MAXN], children[MAXN];
bool isCut[MAXN];
vector<int> adj[MAXN];
bool visited[MAXN];
int n, m;
int nn = 0;
long long ans = 0;
void tarjan(int v, int p){
visited[v] = 1;
tin[v] = curTime++;
low[v] = curTime-1;
nn++;
for(auto u : adj[v]){
if(u == p) continue;
if(visited[u]){
low[v] = min(low[v], tin[u]);
}
else{
children[v].push_back(u);
tarjan(u, v);
low[v] = min(low[v], low[u]);
if(low[u] >= tin[v]){
isCut[u] = 1;
}
}
}
}
void ae(int a, int b){
tree[a].push_back(b);
tree[b].push_back(a);
}
void gen(int v, int b){
if(b != 0) ae(v, b);
for(auto u : children[v]){
if(isCut[u]){
curComp++;
ae(v, curComp);
gen(u, curComp);
}
else{
gen(u, b);
}
}
}
int getSiz(int v, int p){
if(v < n){
int aa = 0;
for(auto u : tree[v]){
if(u == p) continue;
aa += getSiz(u, v)-1;
}
return aa+1;
}
int bb = tree[v].size();
int aa = 0;
for(auto u : tree[v]){
if(u == p) continue;
if(tree[u].size() == 1) continue;
int t = getSiz(u, v);
aa += t;
ans -= 1ll*(tree[v].size()-1)*t*(t-1);
bb--;
}
// ans -= 1ll*bb*aa*(aa-1);
// cout << -1ll*bb*aa*(aa-1) << endl;
// ans += 1ll*bb*(tree[v].size()-bb)*(tree[v].size()-bb-1);
// cout << 1ll*bb*(tree[v].size()-bb)*(tree[v].size()-bb-1) << endl;
if(bb+aa != nn){
ans -= 1ll*(tree[v].size()-1)*(nn-bb-aa+1)*(nn-bb-aa);
// cout << -1ll*(tree[v].size()-1)*(nn-bb-aa+1)*(nn-bb-aa) << endl;
}
// if(v == 11){
// cout << bb+aa << endl;
// }
return bb+aa;
}
int main(){
ios_base::sync_with_stdio(false);
cin.tie(0);
cin >> n >> m;
for(int i = 0; i<m; i++){
int a, b; cin >> a >> b;
--a; --b;
adj[a].push_back(b);
adj[b].push_back(a);
}
curComp = n-1;
for(int i = 0; i<n; i++) if(!visited[i]) {
nn = 0;
tarjan(i, -1);
ans += 1ll*nn*(nn-1)*(nn-2);
gen(i, 0);
getSiz(i, -1);
}
// for(int i = 0; i<n; i++) if(isCut[i]) cout << i+1 << endl;
// for(int i = 0; i<MAXN; i++){
// if(tree[i].size()){
// cout << i+1 << endl;
// for(auto j : tree[i]) cout << j+1 << " ";
// cout << endl << endl;;
// }
// }
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... |