7
1 2 4
1 4 6
2 1 3
2 3 7
3 1 5
3 4 4
4 3 2
ex. 기존에 (2,4)는 무한 이었는데, [2–>1]이 3이고, [1–>4]가 6이라서, 1을 거친 (2,4)가 9로 갱신되었음을 볼 수 있다.
즉, k번째 노드를 거쳐 가는 경우에 갱신 되는 원소들의 조건은
즉, k라는 변수 이용해, 모든 노드에 대해 하나씩 확인하며 해당 노드를 거쳐가는 경우를 고려할 수 있도록 하고, 그 때 마다 매번, 모든 a,b에대해 점화식을 갱신하기 때문에, 이를 구현 할 때는 삼중 반복문을 이용해서 전체 알고리즘을 구현 할 수 있다.
최종
(I Think) 사실 아직 이제 DP라는 것은 잘 이해가 되지 않는다.
다익스트라 알고리즘과 달리, 최소경로 노드를 찾는 과정 없이, 순차적으로, 모든 노드를 k 로 하는 for문을수행한다. (가장 바깥 for 문은, 1번 노드부터 n 번 노드까지 값을 갖는 k 이다)
#include<iostream>
#define NUMBER 4
#define INFINITE 200000000 // 2억
int table[NUMBER][NUMBER]; // 1번 노드 = 0 번 노드
int e; // 간선의 개수
void floyd()
{
for (int k= 0; k < NUMBER; k++) {
for (int a = 0; a < NUMBER; a++) {
for (int b = 0; b < NUMBER; b++) {
if (a != b & a != k & b != k) {
//(a,k) +(k,b)
int temp = table[a][k] + table[k][b];
if (temp < table[a][b]) table[a][b] = temp;
}
}
}
}
}
void printTable()
{
for (int i = 0; i < NUMBER; i++)
for (int j = 0; j < NUMBER; j++) {
printf("%d --> %d :",i + 1, j + 1);
if (table[i][j] == INFINITE) printf("No way to get there\n");
else printf(" %d\n", table[i][j]);
}
}
int main()
{
std::cin >> e;
//초기화
for (int i = 0; i < e; i++) {
int v1, v2,w;
std::cin >> v1 >> v2>>w; // start , end, weight
table[v1 - 1][v2 - 1] = w;
}
// i == i 가 아닌 노드 & 0 값을 갖는 노드 --> 무한 값을 갖도록 한다.
for (int i = 0; i < NUMBER; i++) {
for (int j = 0; j < NUMBER; j++) {
if (i != j & !table[i][j]) table[i][j] = INFINITE; // stdlib에 INFINITY가 defined되어있음.
}
}
floyd();
printTable();
}
파이썬에서 리스트 생성하며 초기화 하는 기법을 따로 정리
INF = int(1e9) # 무한을 의미하는 값으로 10억 설정 #사용자 입력받기 n = int(input()) # 사용자로부터 입력받은 것을 int형으로 변수에 대입 m = int(input()) # 사용자로부터 입력 받은 것을 int형으로 변수에 대입. # 2차원 리스트를 만들며, 초기값을 부여 # 리스트는 이런식으로도 생성이 가능하지 [1]*5 을 하면 [1,1,1,1,1] # 그런데 이것을 n+1 번 한다는 것은, 2차원 list를 만들겠다는 것. graph = [[INF]*(n-1) for _ in range(n+1)]