# | 제출 시각 | 아이디 | 문제 | 언어 | 결과 | 실행 시간 | 메모리 |
---|---|---|---|---|---|---|---|
393975 | 79brue | 철인 이종 경기 (APIO18_duathlon) | C++14 | 258 ms | 41196 KiB |
이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
inline ll c2(ll x) { return x*(x-1)/2; }
inline ll c3(ll x) { return x*(x-1)*(x-2)/6; }
int n, m;
vector<int> link[100002];
ll ans;
void input();
void makeBCC();
void vertexCount();
void lastDFS();
int main(){
input();
makeBCC();
vertexCount();
lastDFS();
printf("%lld", ans);
}
void input(){
scanf("%d %d", &n, &m);
for(int i=1; i<=m; i++){
int x, y;
scanf("%d %d", &x, &y);
link[x].push_back(y);
link[y].push_back(x);
}
}
ll seenCnt;
int dfsn[100002];
int dcnt;
stack<pair<int, int> > stk;
vector<vector<pair<int, int> > > BCC;
vector<int> bccIdx[100002];
vector<int> tlink[200002];
int k;
stack<int> thisComponent;
ll con[200002];
ll vCount[200002];
ll score[200002];
int dfs(int x, int prv = -1){
int result = dfsn[x] = ++dcnt;
seenCnt++;
thisComponent.push(x);
for(auto y: link[x]){
if(prv == y) continue;
if(dfsn[x] > dfsn[y]) stk.push(make_pair(x, y));
if(dfsn[y] > 0) result = min(result, dfsn[y]);
else{
int tmp = dfs(y, x);
result = min(result, tmp);
if(tmp >= dfsn[x]){
vector<pair<int, int> > currBCC;
while(!stk.empty() && stk.top() != make_pair(x, y)){
currBCC.push_back(stk.top());
stk.pop();
}
currBCC.push_back(stk.top());
stk.pop();
BCC.push_back(currBCC);
for(auto p: currBCC){
bccIdx[p.first].push_back((int)BCC.size());
bccIdx[p.second].push_back((int)BCC.size());
}
}
}
}
return result;
}
void makeBCC(){
for(int i=1; i<=n; i++){
if(!dfsn[i]){
seenCnt = 0;
dfs(i);
ans += c3(seenCnt) * 6;
while(!thisComponent.empty()){
con[thisComponent.top()] = seenCnt;
thisComponent.pop();
}
}
}
k = (int)BCC.size(); /// 트리의 정점 개수: n+k
for(int i=1; i<=n; i++){
sort(bccIdx[i].begin(), bccIdx[i].end());
bccIdx[i].erase(unique(bccIdx[i].begin(), bccIdx[i].end()), bccIdx[i].end());
for(auto g: bccIdx[i]){
tlink[i].push_back(g+n);
tlink[g+n].push_back(i);
con[g+n] = con[i];
}
}
}
bool visited[200002];
void dfs2(int x, int prv = -1){
if(x<=n) vCount[x]++;
visited[x] = 1;
for(auto y: tlink[x]){
if(y == prv) continue;
dfs2(y, x);
vCount[x] += vCount[y];
if(x>n){
score[x] += c2(vCount[y]);
}
}
if(x>n) score[x] += c2(con[x] - vCount[x]);
}
void vertexCount(){
for(int i=1; i<=n+k; i++){
if(!visited[i]){
dfs2(i);
}
}
}
void dfs3(int x, int prv = -1){
visited[x] = 1;
for(auto y: tlink[x]){
if(y == prv) continue;
dfs3(y, x);
if(x<=n){
assert(y>n);
ans -= (score[y] - c2(con[x] - vCount[y])) * 2;
}
}
if(x<=n && prv != -1){
ans -= (score[prv] - c2(vCount[x])) * 2;
}
}
void lastDFS(){
fill(visited+1, visited+n+k+1, 0);
for(int i=1; i<=n+k; i++){
if(!visited[i]){
dfs3(i);
}
}
}
컴파일 시 표준 에러 (stderr) 메시지
# | 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... |