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

 

이번에 볼 문제는 백준 21278번 문제인 호석이 두 마리 치킨이다.
문제는 아래 링크를 확인하자.

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

 

주어진 \(N\)의 범위가 매우 작아, Floyd-Warshall 등의 알고리즘을 이용해 모든 건물 사이의 최단거리를 미리 계산할 수 있음을 관찰하자.

 

모든 건물 사이의 최단거리를 알 수 있다면, 남는 것은 치킨집을 열 두 장소 고르는 모든 경우(\(O(N^2)\)가지)에 대하여 모든 각 지점에서 "두 장소까지의 거리 중 최솟값"을 직접 더해보는 것(\(O(N)\))을 반복해 문제를 해결하자. 이 방법의 시간복잡도는 \(O(N^3)\)으로, \(N\)이 충분히 작아 이 방법으로도 문제를 해결할 수 있다.

 

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

#include <iostream>
#include <cstring>
using namespace std;

int N, K;
int dist[101][101];
int ansA, ansB, ansD = 2000000007;

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

	memset(dist, 0x3f, sizeof(dist));
	cin >> N >> K;
	for (int i = 1; i <= N; i++) dist[i][i] = 0;
	while (K--) {
		int x, y; cin >> x >> y;
		dist[x][y] = 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++) {
				dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j]);
			}
		}
	}

	for (int i = 1; i <= N; i++) {
		for (int j = i + 1; j <= N; j++) {
			int val = 0;
			for (int k = 1; k <= N; k++) {
				val += min(dist[k][i], dist[k][j]);
			}
			if (val < ansD) ansD = val, ansA = i, ansB = j;
		}
	}

	cout << ansA << ' ' << ansB << ' ' << ansD * 2;
}
728x90

'BOJ' 카테고리의 다른 글

[BOJ 20917 // C++] 사회적 거리 두기  (0) 2024.06.07
[BOJ 30050 // C++] 트리와 쿼리 \(10^9\)  (0) 2024.06.06
[BOJ 2632 // C++] 피자판매  (0) 2024.06.04
[BOJ 26654 // C++] 원점  (0) 2024.06.03
[BOJ 1635 // C++] 1 또는 -1  (0) 2024.06.02

+ Recent posts