레야몬
[C++] 1865번 웜홀 - 벨만포드 본문
#include <iostream>
#include <vector>
#define MAX_VERTEX 501
#define INF 987654
using namespace std;
int TC, N, M, W; //테스트케이스의 개수, 지점의 수, 도로의 개수, 웜홀의 개수
vector<pair<pair<int, int>, int>> tr; //간선: truck. 시작점, 도착점, 거리가 들어있음
int Dist[MAX_VERTEX]; //최소 거리
int Exist[MAX_VERTEX]; //간선이 존재하는가?
int mi; //첫 번째 탐색 지점, 음수: minus
void Bellman_Ford(int First)
{
Dist[First] = 0;
for(int i=0; i<=N-1; i++) {
for(int j=0; j<tr.size(); j++) {
int From = tr[j].first.first;
int To = tr[j].first.second;
int Cost = tr[j].second;
if(Dist[From] == INF) continue; //이미 탐색이 안된 위치라면 넘기기
if(Dist[To] > Dist[From] + Cost) {
if(i!=N-1) Dist[To] = Dist[From] + Cost; //비용이 더 적으면 갱신하기
else
mi=-1;
}
}
}
for(int i=1; i<=N; i++) {
if(Dist[i]==INF && Exist[i])
Bellman_Ford(i); //분리되어 있는 다른 그래프도 확인
}
}
int main()
{
ios_base::sync_with_stdio(false);
cin.tie(NULL); cout.tie(NULL);
cin >> TC;
for(int i=0; i<TC; i++) {
int S, E, T;//S와 E는 연결된 지점의 번호, T는 이 도로를 통해 이동하는 데 걸리는 시간
cin >> N >> M >> W; //지점의 수, 도로의 개수, 웜홀의 개수
tr.clear(); //tr 초기화
for(int j=1; j<=N; j++) //거리 초기화
Dist[j]=INF;
for(int j=0; j<M; j++) {
cin >> S >> E >> T;
Exist[S]=1, Exist[E]=1;
tr.push_back({{S, E}, T});
tr.push_back({{E, S}, T}); //간선 넣어주기. (방향 없음)
}
for(int j=0; j<W; j++) {
cin >> S >> E >> T;
Exist[E]=1;
tr.push_back({{S, E}, -T}); //웜홀 (방향 있음)
}
mi=0;
Bellman_Ford(S);
if(mi)
cout << "YES" << endl;
else
cout << "NO" << endl;
}
return 0;
}
난 정점이 모두 연결되어야 한다고 생각하였는데 다른 사람의 코드를 보니까 꼭 그러란 법은 없는 것 같다. 정점 1과 모두 연결되어 있는듯 한데 뭐... 아 그리고 벨만 포드 알고리즘을 쓰면서 음수가 되는 회로를 구해야만하는 줄 알았는데 그 전에 자기 자신으로 음수로 돌아오기만 해도 된다고 조건을 추가하면 더 빨라지는 것 같다. 그리고 N번 돌리기 전에 최소 경로가 바뀌지 않으면 넘어간다. 라는 조건도 추가해야하는 것 같다. 참고한 다른 사람의 코드는 아래에 있다.
<벨만-포드 알고리즘 1>
[알고리즘] 벨만-포드 알고리즘 (Bellman-Ford Algorithm)
벨만-포드 알고리즘(Bellman-Ford Algorithm)이란?
velog.io
<벨만-포드 알고리즘 2>
https://sorjfkrh5078.tistory.com/30
벨만-포드 알고리즘(Bellman-Ford Algorithm)
이번에 배워볼 알고리즘은 벨만 포드 알고리즘(Bellman-Ford Algorithm)이다. 이 알고리즘 또한 이전에 배운 다익스트라 알고리즘처럼 그래프에서 한 정점에서 다른 모든 정점으로 가는 최단 경로를
sorjfkrh5078.tistory.com
<다른 분의 코드(맞춰야 볼 수 있습니다.)>
https://www.acmicpc.net/source/22035361
로그인
www.acmicpc.net
※현재 고등학교 등교중인 학생입니다. 이제 알고리즘을 본격적으로 공부하기 시작해서 아직 초보입니다. 혹시 제가 잘못 알고있는 점이나 더 좋은 풀이 방법이 있어 댓글에 남겨주시면 감사히 하나하나 열심히 읽어보겠습니다. 좋아요, 단순한 댓글 한마디라도 저에겐 큰 힘이 됩니다! 감사합니다.
'알고리즘 > 백준' 카테고리의 다른 글
[C++] 1932번 정수 삼각형 - DP (0) | 2022.09.01 |
---|---|
[C++] 1918번 후위 표기식 - 스택 (0) | 2022.09.01 |
[C++] 1753번 최단경로 - 다익스트라 (0) | 2022.09.01 |
[C++] 1629번 곱셈 - 수학, 분할 정복 (0) | 2022.08.31 |
[C++] 1167번 트리의 지름 - 그래프 이론, BFS (1) | 2022.08.31 |