백준
/<> 백준 11403번 : 경로 찾기 (C언어)
모나오랭
2024. 8. 19. 11:15
https://www.acmicpc.net/problem/11403
임의의 노선 (u, v)가 0일 경우, 경유할 수 있는 노선이 (u, a), (a, b), (b, v) 처럼 존재한다면 u에서 v로 갈 수 있다는 뜻이므로 출력은 1로 합니다. 이 문제는 플로이드-워셜(Floyd-Warshall) 알고리즘을 사용하면 됩니다.
플로이드-워셜 알고리즘은 모든 정점 사이의 최단 거리를 구하는 알고리즘입니다. 이 문제는 단순히 갈 수 있냐 없냐 만을 판단하므로, 그냥 출력값을 1로 변경해주면 됩니다.
<코드>
#include <stdio.h>
int n;
int graph[100][100];
void floyd_warshall() {
for(int k = 0; k < n; k++) {
for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++) {
if(graph[i][j] == 0 && graph[i][k] == 1 && graph[k][j] == 1) {
graph[i][j] = 1;
}
}
}
}
}
int main() {
scanf("%d", &n);
for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++) {
scanf("%d", &graph[i][j]);
}
}
floyd_warshall();
for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++) printf("%d ", graph[i][j]);
printf("\n");
}
return 0;
}
최단거리를 구하는 본래의 플로이드-워셜 알고리즘과의 차이점은 다음과 같습니다. 위의 문제에서 노선이 0인 경우에 값을 아주 큰 값(inf)을 부여하고 연산을 진행합니다. 그래서 값의 크기를 비교한 후 변경할 수 있습니다.
void floyd_warshall() {
for(int k = 0; k < n; k++) {
for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++) {
if(graph[i][j] > graph[i][k] + graph[k][j]) {
graph[i][j] = graph[i][k] + graph[k][j];
}
}
}
}
}