PS/BOJ
백준 11266번: 단절점 (C++)
도비(Doby)
2022. 6. 1. 22:46
https://www.acmicpc.net/problem/11266
11266번: 단절점
첫째 줄에 두 정수 V(1≤V≤10,000), E(1≤E≤100,000)가 주어진다. 이는 그래프가 V개의 정점과 E개의 간선으로 이루어져 있다는 의미이다. 다음 E개의 줄에는 간선에 대한 정보를 나타내는 두 정수 A, B
www.acmicpc.net
Solved By: Articulation
처음으로 풀어본 Articulation 문제였습니다. Articulation을 찾는 방법을 설명합니다.
[Solution]
1) DFS를 사용하여 모든 node들의 방문 순서(visitedOrder)를 매깁니다.
2) 특정 A node에서 child node들이 A node를 거치지 않고, A node보다 빠른 visitedOrder를 가진 node로 갈 수 없다면 Articulation으로 판단합니다.
[Exception]
Articulation에는 예외가 존재합니다. A node가 root node일 때, child node가 2개 이상이라면 A node는 무조건 Articulation입니다.
#include <iostream>
#include <vector>
#define MAX 10001
using namespace std;
vector<int> adj[MAX];
int v, e;
int order = 0;
int visitedOrder[MAX];
bool isCut[MAX];
int dfs(int now, bool isRoot){
// minOrder == parent node의 visitedOrder
int minOrder = visitedOrder[now] = ++order;
int child = 0;
for(int i = 0; i < adj[now].size(); i++){
int next = adj[now][i];
if(visitedOrder[next]){
// 이미 order가 있다는 것은 탐색된 정점이라면,
// minOrder를 가져온다.
minOrder = min(visitedOrder[next], minOrder);
continue;
}
child++;
int childOrder = dfs(next, false);
if(!isRoot && visitedOrder[now] <= childOrder){
// 해당 Node가 Root가 아니고, 탐색된 정점들 중
// visitedOrder가 now의 vistedOrder보다 빠른 게 없다면
// Articulation이라고 판단한다.
isCut[now] = true;
}
minOrder = min(minOrder, childOrder);
}
cout << "node: " << now << " minOrder: " << minOrder << '\n';
if(isRoot){
// Root Node이고, child node가 2개 이상이라면 Articulation으로 판단
isCut[now] = (child >= 2);
}
return minOrder;
}
int main(){
cin >> v >> e;
for(int i = 0; i < e; i++){
int a, b; cin >> a >> b;
adj[a].push_back(b);
adj[b].push_back(a);
}
// 하나의 component로 이루어지지 않았을 수도 있으므로
// 모든 정점을 방문하여 visitedOrder가 매겨졌는지 확인한다.
for(int i = 1; i <= v; i++){
if(!visitedOrder[i]){
dfs(i, true);
}
}
int cnt = 0;
for(int i = 1; i <= v; i++){
if(isCut[i]) cnt++;
}
cout << cnt << '\n';
for(int i = 1; i <= v; i++){
if(isCut[i]) cout << i << ' ';
}
return 0;
}