일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- algorithm
- 문제풀이
- network
- 자료구조
- Database
- db
- 법의학
- algogritim
- Computer Science
- 프로그래머스
- swea
- c++
- OS
- D3
- data structure
- BOJ
- 독서
- language
- LeetCode
- 재테크/투자
- 백준
- D2
- 감상문
- 데이터베이스
- 네트워크
- cs
- 알고리즘
- SW Expert Academy
- 운영체제
- Programmers
- Today
- Total
선택은 나의 것
[BOJ 백준] 9370번 미확인 도착지 본문
문제
BOJ 9370 : https://www.acmicpc.net/problem/9370
9370번: 미확인 도착지
문제 (취익)B100 요원, 요란한 옷차림을 한 서커스 예술가 한 쌍이 한 도시의 거리들을 이동하고 있다. 너의 임무는 그들이 어디로 가고 있는지 알아내는 것이다. 우리가 알아낸 것은 그들이 s지��
www.acmicpc.net
접근
이 문제는 출발지(s)에서 목적지 후보까지 가는 최단 거리 루트에서 g-h의 길을 지나는 목적지들을 찾는 문제이다. 이는 다익스트라 알고리즘(Dijkstra algorithm)을 응용하여 풀 수 있다.
우선순위 큐를 이용하여 출발지(s)부터 각 지점까지의 최단 거리를 갱신하며 전진한다. 이때 각 지점까지의 최단 루트가 g-h길을 포함하는지 체크해 나가면서 진행한다.
큰 응용을 요구하는 건 아니지만 푸는 과정에서 몇몇 예외를 간과하는 실수를 하였다. 나는 진행하다가 목적지 후보에 도착하면 continue를 해줬었는데, 다른 목적지 후보 중에 현재 목적지까지의 루트 + α의 루트를 최단 경로로 가질 수 있음으로 continue 해주면 안 된다.
+) 본인은 코드를 짤 때 예를 들면 int next = v[x[i].first] 이런 식으로 가독성 좋게 짜는 편이 아니다..(몇 번을 쓰더라도 변수를 따로 만들지 않고 v[x[i].first]을 그대로 호출한다.) 직관적으로 구조가 보이게 짜기 때문에 코드가 너무 복잡하다고 느껴진다면 vscode로 가지고 가서 직접 치환해보시길 바란다. 코드를 이해하는 데 도움이 될 것이다.
코드
#include <algorithm>
#include <iostream>
#include <queue>
#include <vector>
using namespace std;
struct go {
int point;
int n = 0;
int chk = 0;
};
struct cmp {
bool operator()(go a, go b) {
if (a.n == b.n)
return a.chk >= b.chk;
return a.n < b.n;
}
};
int main() {
int testcase;
cin >> testcase;
for (int t = 0; t < testcase; t++) {
// input
int n, m, tt, s, g, h, goal[2010] = {0};
cin >> n >> m >> tt >> s >> g >> h;
vector<pair<int, int>> map[2010];
for (int i = 0; i < m; i++) {
int a, b, d;
cin >> a >> b >> d;
map[a].push_back(make_pair(b, d));
map[b].push_back(make_pair(a, d));
}
for (int i = 0; i < tt; i++) {
int temp;
cin >> temp;
goal[temp] = 1;
}
// Dijkstra algorithm
priority_queue<go, vector<go>, cmp> q;
q.push({s, 0, 0});
int visit[2010] = {0};
int chk_v[2010] = {0};
while (!q.empty()) {
go temp = q.top();
q.pop();
if (goal[temp.point] == 1 && temp.chk == 1)
goal[temp.point] = -1;
if (temp.chk == 1)
chk_v[temp.point] = 1;
int chk = 0;
for (int i = 0; i < map[temp.point].size(); i++) {
chk = 0;
if ((temp.point == g && map[temp.point][i].first == h) || (temp.point == h && map[temp.point][i].first == g) || temp.chk == 1)
chk = 1;
if ((visit[map[temp.point][i].first] == temp.n + map[temp.point][i].second && chk == 1) && chk_v[map[temp.point][i].first] != 1)
q.push({map[temp.point][i].first, temp.n + map[temp.point][i].second, chk});
else if (visit[map[temp.point][i].first] == 0 || visit[map[temp.point][i].first] > temp.n + map[temp.point][i].second) {
if (goal[map[temp.point][i].first] == -1)
goal[map[temp.point][i].first] = 1;
visit[map[temp.point][i].first] = temp.n + map[temp.point][i].second;
if (chk == 0)
chk_v[map[temp.point][i].first] = 0;
else
chk_v[map[temp.point][i].first] = 1;
q.push({map[temp.point][i].first, temp.n + map[temp.point][i].second, chk});
}
}
}
for (int i = 0; i < 2001; i++) {
if (goal[i] == -1)
cout << i << " ";
}
cout << "\n";
}
return 0;
}
'☽ Algorithm > BOJ' 카테고리의 다른 글
[BOJ 백준] 1543번 문서 검색 (python) (0) | 2020.07.23 |
---|---|
[BOJ 백준] 2812번 크게 만들기 (0) | 2020.07.22 |
[BOJ 백준] 1786번 찾기 (0) | 2020.07.13 |
[BOJ 백준] 1456번 거의 소수 (0) | 2020.07.10 |
[BOJ 백준] 2841번 외계인의 기타 연주 (0) | 2020.07.10 |