https://www.acmicpc.net/problem/16947
이 문제도 어느 게임회사 코테에 나왔던 문제였다 코테풀기전에 이문제를 풀었다면 좋았었을텐데 지금에서야 접했다
이문제는 사이클이 하나만 있다고 가정하고 그래프릍 탐색해서 순환 구조를 파악하는 문제이다
첫 번째로 사이클을 탐색하는 규칙은 자신으로 왔을떄 자신의 이전 노드들을 저장하고 있는다 그리고 만약에 다음노드를 방문했을때 이노드가 방문되어있고 이노드에 저장되어있던 노드가 지금 노드와 다르다면 이노드는 순환구조를 만든 노드라고 파악한다
이에 대한 코드는 아래와 같다
void findCycle(int cur) {
isVisited[cur] = true;
for (int i = 0; i < vertex[cur].size(); i++) {
if (hasCycle)
return;
int next = vertex[cur][i];
if (isVisited[next]) {
if (next != pre[cur]) {
cycle[cur] = true;
hasCycle = true;
while (cur != next) {
cycle[pre[cur]] = true;
cur = pre[cur];
}
return;
}
}
else {
pre[next] = cur;
findCycle(next);
}
}
}
이렇게 dfs를 통해 방문 한 노드에 대해서 이전노드들을 검사해준다 그후 순환 노드가 파악이되었으면 pre 배열을 통해 이전 노드들을 파악해서 cycle로 체크를 해준다
이제 cycle로부터 각 노드들이 얼만큼 떨어져 있는 지 계산한다
void bfs() {
queue<pair<int, int>> q;
for (int i = 1; i <= n; i++) {
if (cycle[i]) {
isVisited[i] = true;
q.push({ i,0 });
}
}
while (!q.empty()) {
int cur = q.front().first;
int dis = q.front().second;
q.pop();
isVisited[cur] = true;
for (int i = 0; i < vertex[cur].size(); i++) {
int next = vertex[cur][i];
if (isVisited[next])
continue;
dist[next] = dis + 1;
q.push({ next, dis + 1 });
}
}
}
bfs를 통해 판별한다
전체 코드는 아래와같다
#include <iostream>
#include <vector>
#include <queue>
#include<cstring>
using namespace std;
bool isVisited[3001];
int pre[3001];
bool cycle[3001];
int dist[3001];
vector<int> vertex[3001];
int n;
bool hasCycle;
void bfs() {
queue<pair<int, int>> q;
for (int i = 1; i <= n; i++) {
if (cycle[i]) {
isVisited[i] = true;
q.push({ i,0 });
}
}
while (!q.empty()) {
int cur = q.front().first;
int dis = q.front().second;
q.pop();
isVisited[cur] = true;
for (int i = 0; i < vertex[cur].size(); i++) {
int next = vertex[cur][i];
if (isVisited[next])
continue;
dist[next] = dis + 1;
q.push({ next, dis + 1 });
}
}
}
void findCycle(int cur) {
isVisited[cur] = true;
for (int i = 0; i < vertex[cur].size(); i++) {
if (hasCycle)
return;
int next = vertex[cur][i];
if (isVisited[next]) {
if (next != pre[cur]) {
cycle[cur] = true;
hasCycle = true;
while (cur != next) {
cycle[pre[cur]] = true;
cur = pre[cur];
}
return;
}
}
else {
pre[next] = cur;
findCycle(next);
}
}
}
int main() {
cin >> n;
int tmp1, tmp2;
for (int i = 0; i < n; i++) {
cin >> tmp1 >> tmp2;
vertex[tmp1].push_back(tmp2);
vertex[tmp2].push_back(tmp1);
}
findCycle(1);
memset(isVisited, false, 3001);
bfs();
for (int i = 1; i <= n; i++) {
cout << dist[i] << ' ';
}
}
'백준(코테준비) > DFS,BFS' 카테고리의 다른 글
백준 1941 / 소문난 칠공주 / C++ / dfs / bfs / 브루트포스 (0) | 2025.03.06 |
---|---|
백준 13460 / CPP / bfs (0) | 2025.01.14 |
백준 2638/C++ (0) | 2024.11.19 |
백준 16234 / C++ (0) | 2024.08.17 |
백준 1520 / C++ (0) | 2024.08.07 |