| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 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 |
Tags
- 그래프 탐색
- 비트마스킹
- Strongly Connected Component
- localstorage
- SCC
- Spin Lock
- Express.js
- R 그래프
- ccw 알고리즘
- 벨만-포드
- 분리 집합
- MongoDB
- 비트필드를 이용한 dp
- Binary Lifting
- 2-SAT
- 트라이
- 최소 공통 조상
- trie
- DP
- 게임 서버 아키텍처
- Github
- JavaScript
- 이분 탐색
- Prisma
- 강한 연결 요소
- PROJECT
- map
- 자바스크립트
- Behavior Design Pattern
- LCA
Archives
- Today
- Total
dh_0e
[PS] 골목길 / C++ (백준 1738번) 본문
역시 벨만-포드 알고리즘이 기본이 되는 문제로, 1에서 n까지 가는 길에 양의 사이클이 포함되어 있는지 확인하면서 n까지 가는 경로를 출력하는 문제.
풀이 과정
오민식의 고민(백준 1219번)의 풀이처럼 벨만-포드 알고리즘을 적절히 구현하여 나올 수 있는 경우의 수를 모두 구해본다.
- n까지 가는 경로 X: -1 출력
- n 도착: 경로 출력
- 무한 증가: -1 출력 (무한 증가 사이클의 교차점들에서 n까지 가는 경로가 존재할 때)
- 무한 감소: 무시
- dfs나 bfs로 무한 증가 사이클의 교차점들에서 n까지 가는 경로가 존재하는지 확인한다.
- 이때, 인접 행렬을 사용하면 편하며, 한 번 방문한 node에선, n까지 도달했으면 이미 flag를 체크했을 것이기 때문에 visit 체크를 0으로 초기화하는 과정은 모든 경로 탐색이 끝난 뒤에 해주어야 한다.
- 경로를 저장하는 방법으로는 처음엔 vector로 저장했다가 시간 초과가 나와서, be[i]: "cost[i] 값을 갱신한 i의 이전 교차로" 배열을 사용하여 마지막에 역추적하여 출력하는 방식으로 바꿨다.
- 역추적 과정에서 사이클에 빠지는 것을 걱정할 필요가 없는 게 이전에 dfs를 돌면서 사이클을 모두 확인하기 때문에 최적의 경로가 존재하는 경우에만 역추적 함수로 들어가서 출력한다.
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
int n, m, flag = 0;
int cost[101], before[101], vi[101], be[101];
int d[101][101];
vector<pair<pair<int, int>, int> > alley;
void bellmanford()
{
int size = alley.size();
for (int i = 0; i < size; i++) {
int u = alley[i].first.first, v = alley[i].first.second, w = alley[i].second;
if (cost[u] == 2e9)continue;
if (cost[v] == 2e9 || cost[v] < cost[u] + w) {
cost[v] = cost[u] + w;
be[v] = u;
}
}
return;
}
void dfs(int p)
{
if (p == n) {
flag = 1;
return;
}
for (int i = 1; i <= n; i++) {
if (d[p][i]&&!vi[i]) {
vi[i] = 1;
dfs(i);
}
}
return;
}
void print(int p) {
if (be[p] == -1) {
printf("1 ");
return;
}
else {
print(be[p]);
printf("%d ", p);
return;
}
}
int main()
{
scanf("%d %d", &n, &m);
for (int i = 1; i <= m; i++) {
int u, v, w;
scanf("%d %d %d", &u, &v, &w);
alley.push_back(make_pair(make_pair(u, v), w));
d[u][v] = 1;
}
for (int i = 1; i <= n; i++)cost[i] = 2e9;
cost[1] = 0; be[1] = -1;
for (int i = 1; i < n; i++)bellmanford();
for (int i = 1; i <= n; i++)before[i] = cost[i];
bellmanford();
if (cost[n] == 2e9) {
printf("-1\n");
return 0;
}
for (int i = 1; i <= n; i++) {
if (before[i] != cost[i]) {
flag = 0;
vi[i] = 1;
dfs(i);
for (int j = 1; j <= n; j++)vi[j] = 0;
if (flag) {
printf("-1\n");
return 0;
}
}
}
print(n);
return 0;
}'Problem Solving > Baekjoon' 카테고리의 다른 글
| [PS] 비숍 / C++ (백준 1799번) (0) | 2026.01.02 |
|---|---|
| [PS] 피보나치 수 6 / C++ (백준 11444번) (0) | 2025.12.26 |
| [PS] 오민식의 고민 / C++ (백준 1219번) (0) | 2025.12.18 |
| [PS] 타임머신, 웜홀 (벨만-포드 기초) / C++ (백준 11675, 1865번) (0) | 2025.12.17 |
| [PS] 다리 만들기 2 / C++ (백준 17472번) (1) | 2025.09.09 |