리뷰
https://www.acmicpc.net/problem/13023
N이 2000이라 가지치기가 필요할 것이라 생각했는데 그냥 제출해도 되는 문제였다.
전역 변수
- N : 배열의 최대 크기를 정의할 상수 변수
- n : 사람의 수를 저장할 변수
- m : 친구 관계의 수를 저장할 변수
- ans : 정답 여부를 저장할 변수
- v : 방문 정보를 저장할 배열
- edges : 인접 리스트를 저장할 배열
함수
1. dfs
void dfs(int level, int node)
깊이 우선 탐색을 통해 연속된 5명의 친구 관계가 있는지 체크하는 함수
- 매개 변수로 재귀 단계 level과 현재 노드 번호 node를 전달 받는다.
- 기저 조건으로 재귀 단계가 5가 될 경우 ans를 true로 변환 후 return 처리한다.
- node의 인접 리스트를 순회하며 방문 된 번호가 아닐 경우 방문 처리 후 재귀 단계를 올려 재귀를 진행한다.
- 재귀를 마친 후에 빠져나오며 방문 처리를 해제해 준다.
문제풀이
- n, m값을 입력 받고, m개의 간선 정보를 입력 받아 인접 리스트 edges에 양방향 간선으로 추가해 준다.
- 0~n - 1번을 순회하며 방문 처리 후 dfs함수에 초기 재귀 레벨 1과 노드 번호 i를 전달하여 재귀를 수행한다.
- 재귀를 빠져나온 후 ans가 true일 경우 1을 출력하고 리턴해 준다.
- 만약 탐색이 종료된 후에도 ans가 false라면 0을 출력해 준다.
트러블 슈팅
- 가지치기를 위해 재귀 레벨 5까지 도달하지 못한 경우 해당 경로의 친구들은 dfs를 수행하지 않게 해주었다.
- 하지만 위 방법은 모든 상태를 체크할 수 없는 듯 하여 제거해 주니 AC를 받았다.
참고 사항
- 대충 계산해 보니 재귀 단계가 최대 5이므로 최악의 케이스에도 2000 * 2^5 정도로 처리가 가능해 보인다.
정답 코드
#include<iostream>
#include<vector>
using namespace std;
const int N = 2000;
int n, m;
bool ans;
bool v[N];
vector<int> edges[N];
void dfs(int level, int node) {
if (level == 5) {
ans = true;
return;
}
for (int i : edges[node]) {
if (v[i]) continue;
v[i] = true;
dfs(level + 1, i);
v[i] = false;
}
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cin >> n >> m;
while (m--) {
int a, b; cin >> a >> b;
edges[a].push_back(b);
edges[b].push_back(a);
}
for (int i = 0; i < n; ++i) {
v[i] = true;
dfs(1, i);
v[i] = false;
if (ans) {
cout << 1;
return 0;
}
}
cout << 0;
}
728x90
'알고리즘 공부 > C++' 카테고리의 다른 글
[G4] 백준 25577번 열 정렬정렬 정 C++ 해시맵, 정렬 (0) | 2025.03.01 |
---|---|
[G3] 백준 9466번 텀 프로젝트 C++ 깊이 우선 탐색 (0) | 2025.03.01 |
[P2] 백준 15899번 트리와 색깔 C++ 세그먼트 트리, 오일러 경로 테크닉, 머지 소트 트리 (0) | 2025.02.27 |
[S1] 백준 29197번 아침 태권도 C++ 수학, 기하학, 해시맵 (0) | 2025.02.26 |
[G5] 백준 19940번 피자 오븐 C++ 너비 우선 탐색 (0) | 2025.02.26 |