※ 글쓴이는 취미로 코딩을 익혀보는 사람이라 정확하지 않은 내용을 담고 있을 수 있다 ※

 

이번에 볼 문제는 백준 11562번 문제인 백양로 브레이크이다.
문제는 아래 링크를 확인하자.

www.acmicpc.net/problem/11562

 

11562번: 백양로 브레이크

서울 소재 Y모 대학교에서 대규모 공사를 진행하면서, 학교가 마치 미로처럼 변해버리고 말았다. 공사 이전까지는 어떤 건물에서 출발하더라도 다른 모든 건물로 갈 수 있는 길이 있었으나, 공

www.acmicpc.net

이 문제를 해결하기 위해 먼저 간단한 관찰을 하자.

 

한 건물에서 다른 건물로 가는 경로는 (일방통행 길을 반대 방향으로 지나가는 경우를 포함하여) 여러 개가 있을 수 있다. 이 문제에서는 이 경로들 중 "일방통행 길을 반대 방향으로 지나가는 횟수"가 최소인 경우의 그 횟수를 구해야한다.

 

따라서, 일방통행 길을 반대방향으로 지날 때마다 가중치가 1씩 늘어나게 그래프를 만들면 최단경로 알고리즘을 통해 한 점에서 다른 점으로 가는 가장 가중치가 적은 경로와 그때의 가중치(일방통행 길을 반대방향으로 지난 횟수)를 구할 수 있게 된다.

 

이 문제에서는 여러 쌍의 점에 대하여 질의가 들어오므로, 미리 모든 쌍의 점에 대한 가중치를 계산할 수 있는 Floyd-Warshall(플로이드-워셜) 알고리즘을 이용하는 것이 좋다.

글쓴이 기준으로 이 문제를 dijkstra로 풀어 제출하였을 때에는 864ms, Floyd-Warshall로 풀어 제출하였을 때에는 24ms의 시간이 걸렸다.

 

아래는 제출한 소스코드이다.

#include <iostream>
using namespace std;

int dist[251][251];

int main() {
	ios::sync_with_stdio(0);
	cin.tie(0);

	int N, M; cin >> N >> M;
	
	for (int i = 1; i <= N; i++) {
		for (int j = 1; j <= N; j++) {
			dist[i][j] = 999;
		}
	}
	for (int i = 1; i <= N; i++) dist[i][i] = 0;

	while (M--) {
		int x, y, z; cin >> x >> y >> z;
		dist[x][y] = 0;
		if (z) dist[y][x] = 0;
		else dist[y][x] = 1;
	}

	for (int k = 1; k <= N; k++) {
		for (int i = 1; i <= N; i++) {
			for (int j = 1; j <= N; j++) {
				int temp = dist[i][k] + dist[k][j];
				if (dist[i][j] > temp) dist[i][j] = temp;
			}
		}
	}

	int K; cin >> K;
	while (K--) {
		int s, e; cin >> s >> e;
		cout << dist[s][e] << '\n';
	}
}
728x90

'BOJ' 카테고리의 다른 글

[BOJ 1865 // C++] 웜홀  (0) 2021.05.15
[BOJ 11563 // C++] 연돌이와 고잠녀  (0) 2021.05.14
[BOJ 1183 // C++] 약속  (0) 2021.05.12
[BOJ 11561 // C++] 징검다리  (0) 2021.05.11
[BOJ 11560 // C++] 다항식 게임  (0) 2021.05.10

+ Recent posts