일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- 백준 2178
- 2636
- 백준 2206
- 백준 2470
- boj 2667
- boj 1697
- 백준 2635
- 2167
- 백준 1697
- boj 19238
- boj 2108
- boj 2661
- boj 2178
- 백준 2636
- 백준 1503
- 백준 10800
- boj 1806
- boj 2206
- boj 2635
- 10800
- boj 1503
- boj 2636
- 백준 19238
- 백준 1806
- 백준 2108
- boj 2167
- 백준 2661
- boj 10800
- 백준 2167
- boj 2470
- Today
- Total
말랑말랑한 개발자 이야기
[백준 14496번] 그대, 그머가 되어 본문
[백준 14496번] 그대, 그머가 되어
문제
선린에 합격한 대호에게는 큰 고민이 있다. 대호는 중학교 3년 내내 공부만 했기 때문에, 요즘 학생들이 사용하는 ‘야민정음’에 대해서는 문외한이다. 친구들의 대화에 끼고 싶은 대호는 야민정음을 공부하기로 했다.
야민정음이란, 비슷한 모양의 글자를 원래 문자 대신에 사용하는 것을 일컫는다. 예를 들어, ‘그대’는 ‘그머’로, ‘팔도비빔면’은 ‘괄도네넴댼’으로, ‘식용유’는 ‘식용윾’으로, ‘대호’는 ‘머호’로 바꿀 수 있다. 아무 문자나 치환할 수 있는 건 아니며 치환이 가능한 몇 개의 문자들이 정해져있다.
예를 들어보자. (a, b), (a, c), (b, d), (c, d)가 주어지는 경우, a를 d로 바꾸는 방법은 a-b-d, a-c-d로 2개가 있다. (a, b), (b, c), (a, c)가 주어지는 경우, a를 c로 바꾸는 방법은 a-b-c, a-c의 2개가 있다. 하지만 이 경우에는 치환횟수에 차이가 생기게 된다.
머호는 문자 a를 문자 b로 바꾸려하고, N개의 문자와 치환 가능한 문자쌍 M개가 있다. 머호에게 a를 b로 바꾸기 위한 치환의 최소 횟수를 구해서 머호에게 알려주자!
프로그램 작성의 편의를 위해, 머호가 공부하는 모든 문자는 자연수로 표현되어 주어진다.
입력
첫째 줄에 머호가 바꾸려 하는 문자 a와 b가 주어진다. 둘째 줄에 전체 문자의 수 N과 치환 가능한 문자쌍의 수 M이 주어진다. (1 <= N <= 1,000, 1 <= M <= 10,000) 이후 M개의 줄에 걸쳐 치환 가능한 문자쌍이 주어진다. 모든 문자는 N이하의 자연수로 표현된다.
출력
a를 b로 바꾸기 위해 필요한 최소 치환 횟수를 출력한다. 치환이 불가능한 경우는 –1을 출력한다.
풀이
#include <iostream>
#include <queue>
#include <vector>
using namespace std;
bool check[1001];
vector<int> v[1001];
int bfs(int a, int target){
queue<pair<int, int>> q;
q.push(make_pair(a, 0));
while(!q.empty()){
int k = q.front().first;
int cnt = q.front().second;
q.pop();
if(k == target){
return cnt;
}
for(int i=0;i<v[k].size();i++){
int kk = v[k][i];
if(check[kk]) continue;
check[kk] = true;
q.push(make_pair(kk, cnt+1));
}
}
return -1;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(NULL); cout.tie(NULL);
int a, b; cin >> a >> b;
int N, M; cin >> N >> M;
for(int i=0;i<M;i++){
int q, w; cin >> q >> w;
v[q].push_back(w);
v[w].push_back(q);
}
cout << bfs(a, b);
return 0;
}
거의 한 3주간 시험기간에, 종강에 치여 살다가 문제는 많이 풀었는데 블로그에 포스팅을 하지 못했다. 몰아서 올리는데 그 첫번째 문제이다. 그래프 형식의 BFS 문제로, 노드와 엣지를 갖는 그래프 문제는 vector<int> arr[N] 을 선언해서 풀면 쉽게 생각할 수 있다. a부터 BFS를 시작하여 b가 나오면 종료한다. BFS를 돌면서 방문처리는 필수이다. 조건만 잘 지키면 쉽게 풀린다.
'알고리즘 > 백준' 카테고리의 다른 글
[백준 21318번] 피아노 체조 (0) | 2021.06.18 |
---|---|
[백준 20438번] 출석체크 (0) | 2021.06.18 |
[백준 1260번] DFS와 BFS (0) | 2021.05.23 |
[백준 9024번] 두 수의 합 (0) | 2021.05.23 |
[백준 14430번] 자원 캐기 (0) | 2021.05.23 |