본문 바로가기

알고리즘 관련/BOJ

1719 택배

https://www.acmicpc.net/problem/1719

 

1719번: 택배

명우기업은 2008년부터 택배 사업을 새로이 시작하기로 하였다. 우선 택배 화물을 모아서 처리하는 집하장을 몇 개 마련했지만, 택배 화물이 각 집하장들 사이를 오갈 때 어떤 경로를 거쳐야 하

www.acmicpc.net

N이 작고, 시간 제한이 작기 때문에 플로이드 와샬 알고리즘으로 시간 내에 수행이 가능하다.

답안의 요구사항이 제일 첫 번째로 경유하는 지점을 출력하는 것이므로, 최단 거리 갱신을 수행하는 과정에서 시작 지점을 갱신하는 것이 핵심이다.

answer[i][j] = i에서 j로 가기 위한 첫 번째 경유 지점

1. 처음에 입력을 받으면서 시작 지점을 저장한다.

2. 최단거리 갱신 과정에서 경유하는 지점을 기록한다.

 

고찰

첫 번째 시작 지점을 갱신하는 로직을 answer[i][j] = k로 했더니, 틀린 답이 나왔다.

경유하는 지점이 한 개만 있는게 아니기 때문에 틀렸다는걸 알게 되었고, answer[i][j] = answer[i][k]로 수정했다.

플로이드의 최단거리 메커니즘과 유사하게 첫 번째 경유지점을 갱신할 수 있기 때문에 위와 같이 작성하였다.

 

정답코드

더보기
#include <iostream>
using namespace std;
#define MAX_SIZE 201
#define INF 987654321
int N, M;
int dist[MAX_SIZE][MAX_SIZE];
int answer[MAX_SIZE][MAX_SIZE];
//최단거리 갱신을 위한 초기화
void setting()
{
	for (int i = 1; i <= N; i++) {
		for (int j = 1; j <= N; j++) {
			if (i == j)
				continue;
			dist[i][j] = INF;
		}
	}
}
void floyd()
{
	for (int k = 1; k <= N; k++) {
		for (int i = 1; i <= N; i++) {
			for (int j = 1; j <= N; j++) {
				if (i == j)
					continue;
				if (dist[i][j] > dist[i][k] + dist[k][j]) {
					answer[i][j] = answer[i][k]; //시작 지점 갱신
					dist[i][j] = dist[i][k] + dist[k][j];
				}
			}
		}
	}
}
int main()
{
	cin >> N >> M;
	setting();
	for (int i = 0; i < M; i++) {
		int s, e, d;
		scanf("%d %d %d", &s, &e, &d);
		dist[s][e] = d;
		answer[s][e] = e;
		dist[e][s] = d;
		answer[e][s] = s;
	}
	floyd();
	for (int i = 1; i <= N; i++) {
		for (int j = 1; j <= N; j++) {
			if (i == j)
				printf("- ");
			else
				printf("%d ", answer[i][j]);
		}
		printf("\n");
	}
	return 0;
}

'알고리즘 관련 > BOJ' 카테고리의 다른 글

4485 녹색 옷 입은 애가 젤다지?  (0) 2021.10.18
15971 두 로봇  (0) 2021.10.11
15658 연산자 끼워넣기(2)  (0) 2021.06.22
20152 Game Addiction  (0) 2021.06.15
1655 가운데를 말해요  (0) 2021.04.28