이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#include "bits/stdc++.h"
using namespace std;
#define ar array
const int N = 1e6 + 5;
vector<int> edges[N], ee[N];
int tin[N], low[N], used[N];
int last, t;
vector<ar<int, 2>> ss;
void dfs(int u, int p = -1){
tin[u] = low[u] = ++t;
used[u] = 1;
int c = 0;
for(auto x : edges[u]){
if(x == p) continue;
if(used[x]){
if(low[u] > tin[x]){
low[u] = tin[x];
ss.push_back({u, x});
}
} else { ++c;
ss.push_back({u, x});
dfs(x, u);
low[u] = min(low[u], low[x]);
if(p == -1 && c > 1){
last++;
while(ss.back() != (ar<int, 2>){u, x}){
ee[ss.back()[0]].push_back(last);
ee[ss.back()[1]].push_back(last);
ss.pop_back();
} ss.pop_back();
ee[u].push_back(last);
ee[x].push_back(last);
}
if(~p && low[x] >= tin[u]){
last++;
while(ss.back() != (ar<int, 2>){u, x}){
ee[ss.back()[0]].push_back(last);
ee[ss.back()[1]].push_back(last);
ss.pop_back();
} ss.pop_back();
ee[u].push_back(last);
ee[x].push_back(last);
}
}
}
}
int sub[N], n, m, res;
void dfs2(int u, int p = -1){
//~ cout<<u<<endl;
sub[u] = (u <= n);
for(auto x : ee[u]){
if(x == p) continue;
dfs2(x, u);
sub[u] += sub[x];
}
}
int tot;
void dfs3(int u, int p = -1){
used[u] = 1;
if(u <= n){
for(auto x : ee[u]){
if(x == p) continue;
dfs3(x, u);
}
} else {
int sz = ee[u].size();
assert(sz >= 2);
for(auto x : ee[u]){
if(x == p){
res -= (tot - sub[u]) * (tot - sub[u] - 1) * (sz - 1);
} else {
res -= sub[x] * (sub[x] - 1) * (sz - 1);
dfs3(x, u);
}
}
}
}
signed main(){
ios::sync_with_stdio(0); cin.tie(0);
cin>>n>>m;
for(int i=0;i<m;i++){
int a, b; cin>>a>>b;
edges[a].push_back(b);
edges[b].push_back(a);
}
for(int i=1;i<=n;i++){
if(used[i]) continue;
dfs(i);
last++;
while(!ss.empty()){
ee[ss.back()[0]].push_back(last);
ee[ss.back()[1]].push_back(last);
ss.pop_back();
}
}
for(int i=1;i<=n;i++){
sort(ee[i].begin(), ee[i].end());
ee[i].erase(unique(ee[i].begin(), ee[i].end()), ee[i].end());
for(auto& x : ee[i]){
x += n;
ee[x].push_back(i);
}
}
//~ last += n;
//~ for(int i=1;i<=n;i++){
//~ for(auto x : ee[i]) cout<<i<<" "<<x<<"\n";
//~ } cout<<last<<endl;
memset(used, 0, sizeof used);
for(int i=1;i<=n;i++){
if(used[i]) continue;
//~ cout<<i<<endl;
dfs2(i);
res += sub[i] * (sub[i] - 1) * (sub[i] - 2);
tot = sub[i];
dfs3(i);
}
cout<<res<<"\n";
}
/*
4 3
1 2
2 3
3 4
4 4
1 2
2 3
3 4
4 2
*/
# | 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... |