-
[Graph] BOJ 13023 : ABCDE백준 문제풀이/GRAPH 2019. 7. 18. 08:52
백준 알고리즘 강의를 토대로 작성된 문제풀이입니다.
문제
BOJ 알고리즘 캠프에는 총 N명이 참가하고 있다. 사람들은 0번부터 N-1번으로 번호가 매겨져 있고, 일부 사람들은 친구이다.
오늘은 다음과 같은 친구 관계를 가진 사람 A, B, C, D, E가 존재하는지 구해보려고 한다.
-
A는 B와 친구다.
-
B는 C와 친구다.
-
C는 D와 친구다.
-
D는 E와 친구다.
위와 같은 친구 관계가 존재하는지 안하는지 구하는 프로그램을 작성하시오.
입력
첫째 줄에 사람의 수 N (5 ≤ N ≤ 2000)과 친구 관계의 수 M (1 ≤ M ≤ 2000)이 주어진다.
둘째 줄부터 M개의 줄에는 정수 a와 b가 주어지며, a와 b가 친구라는 뜻이다. (0 ≤ a, b ≤ N-1, a ≠ b) 같은 친구 관계가 두 번 이상 주어지는 경우는 없다.
출력
문제의 조건에 맞는 A, B, C, D, E가 존재하면 1을 없으면 0을 출력한다.
풀이
문제를 한마디로 정리해보자면
" 다섯명의 꼬리를 무는 관계를 찾아라. "
라고 할 수 있다.
간단해 보이지만 입력부터 많은 생각을 고려할 필요가 있다.
우선 3개의 배열을 만든다.
1. 인접배열로 그래프의 정보를 저장하는 2차원 배열
2. 모든 간선을 저장할 배열
3. 마지막 E 의 관계를 찾기위한 배열
(3번 배열을 만든 이유는 마지막에 설명)
배열을 모두 선언하고 for 문을 통해서 입력을 받을건데
A 와 B 가 친구라면 A -> B 도 성립되고
B -> A 도 성립된다.
따라서 이 그래프는 무방향 그래프가 될것이고
간선을 입력할때 두 방향 모두 입력할 필요가있다.
입력이 모두 끝나면 모든 간선을 돌면서 연속적인 친구관계를 찾아야 한다.
무방향 그래프로 인해서 간선의 개수가 두배가 되었기 때문에
입력된 간선의 두배만큼 탐색을한다.
가장 처음에 i 와 j 번째의 간선 관계를 확인한다.
이때 선택된 간선의 정점이 한개도 겹치지 않는 두 간선을 찾는다!!.
그렇게 되면 사람 A,B,C,D 가 나올것이고
필연적으로 A - B , C - D 두개의 친구 관계가 생긴다.
여기서 우리는 B - C 의 관계만 확인해주면 4개의 연속적인 관계를 확인할 수 있다.
이 정보는 미리 저장해두었던 인접그래프에서 찾을 수 있다.
자, 여기까지 2개의 배열을 사용해서 4개의 연속적인 관계를 확인했다.
이제 마지막 5번째 친구만 확인하면 된다.
이건 간단한게 D 의 친구가 앞에서 정해진 A,B,C 만 아니면 된다.
이때 우리는 3번째 배열을 사용해서 간단하게 찾을 수 있다.
3번째 배열은 마치 인접리스트와 느낌이 비슷하기 때문에
한 정점에 대한 간선을 쉽게 찾을 수 있다.
이렇게 모든 조건이 성립되는 관계가 존제할때 1을 출력한다.
코드
#include <iostream> #include <vector> #include <algorithm> using namespace std; bool a[2000][2000]; // 그래프 vector<int> g[2000]; //E 를 쉽게 찾기위한 배열 vector<pair<int, int>> edges; //간선 int main() { int n, m; cin >> n >> m; for (int i = 0; i < m; i++) { int from, to; cin >> from >> to; edges.push_back({ from, to }); //무방향 그래프 edges.push_back({ to, from }); a[from][to] = a[to][from] = true; g[from].push_back(to); g[to].push_back(from); } m *= 2; //관계하나에 간선이 두개씩 추가됨 for (int i = 0; i < m; i++) { for (int j = 0; j < m; j++) { // A -> B int A = edges[i].first; int B = edges[i].second; // C -> D int C = edges[j].first; int D = edges[j].second; if (A == B || A == C || A == D || B == C || B == D || C == D) { continue; } // B -> C if (!a[B][C]) { continue; } // D -> E for (int E : g[D]) { if (A == E || B == E || C == E || D == E) { continue; } cout << 1 << '\n'; return 0; } } } cout << 0 << '\n'; return 0; }
'백준 문제풀이 > GRAPH' 카테고리의 다른 글
[BFS] BOJ 2178 : 미로 탐색 (0) 2019.08.16 [BFS] BOJ 4963 : 섬의 개수 (0) 2019.08.15 [BFS] BOJ 2667 : 단지번호붙이기 (0) 2019.08.14 [BFS] BOJ 11724 : 연결 요소 (2) 2019.07.24 [Graph] BOJ 1260 : DFS 와 BFS (0) 2019.07.22 -