/* SPDX-License-Identifier: MIT */ /* * Imbus 2025 * * PQ-less dijkstra in quadratic complexity */ #include #include #define DIM 26 #define A 0 #define B 1 #define C 2 #define D 3 #define E 4 #define F 5 #define G 6 #define H 7 #define I 8 #define J 9 #define K 10 #define L 11 #define M 12 #define N 13 #define O 14 #define P 15 #define Q 16 #define R 17 #define S 18 #define T 19 #define U 20 #define V 21 #define W 22 #define X 23 #define Y 24 #define Z 25 /* Node to character */ #define ntoch(n) ('A' + (char)(n % 26)) /* Some helpers */ #define set_dist(from, to, d) g[((int)from)][((int)to)] = (int)d #define get_dist(from, to) g[((int)from)][((int)to)] /* Adjacency matrix */ int g[DIM][DIM] = {}; void printmat(int mat[DIM][DIM]) { printf("## "); for (int h = 0; h < DIM; h++) printf("%c ", ntoch(h)); printf("\n"); printf(" "); for (int h = 0; h < DIM; h++) printf("%s", "__"); printf("\n"); for (int i = 0; i < DIM; i++) { printf("%c |", ntoch(i)); for (int j = 0; j < DIM; j++) { printf("%c ", ntoch(mat[i][j])); } printf("\n"); } } void dijkstra(int mat[DIM][DIM], int prev[DIM], int dist[DIM], int s) { int visited[DIM] = {0}; for (int i = 0; i < DIM; i++) { dist[i] = INT_MAX; prev[i] = -1; } dist[s] = 0; prev[s] = 0; for (int i = 0; i < DIM; i++) { // Pick first unvisited with smallest dist int u = -1; int min = INT_MAX; for (int j = 0; j < DIM; j++) { if (!visited[j] && dist[j] < min) { min = dist[j]; u = j; } } if (u == -1) break; visited[u] = 1; for (int v = 0; v < DIM; v++) { if (get_dist(u, v) > 0 && !visited[v]) { if (dist[u] + get_dist(u, v) < dist[v]) { dist[v] = dist[u] + get_dist(u, v); prev[v] = u; } } } } } void path_reconstruct(int prev[DIM], int dist[DIM], int s, int t) { if (dist[t] == INT_MAX) { printf("No path from %c to %c\n", ntoch(s), ntoch(t)); return; } int path[DIM]; int len = 0; // Walk backwards from target to source for (int v = t; v != -1; v = prev[v]) { path[len++] = v; if (v == s) break; } if (path[len - 1] != s) { printf("No path from %c to %c\n", ntoch(s), ntoch(t)); return; } // Print path in correct order printf("Path (cost %d): ", dist[t]); for (int i = len - 1; i >= 0; i--) { printf("%c", ntoch(path[i])); if (i > 0) printf(" -> "); } printf("\n"); } void init_graph(void) { set_dist(A, B, 4); set_dist(A, C, 9); set_dist(B, D, 2); set_dist(B, E, 5); set_dist(C, B, 2); set_dist(C, F, 7); set_dist(D, C, 1); set_dist(E, C, 2); set_dist(F, G, 3); set_dist(G, H, 6); set_dist(H, I, 1); set_dist(I, J, 8); set_dist(J, K, 4); set_dist(K, L, 5); set_dist(L, M, 2); set_dist(M, N, 3); set_dist(N, O, 7); set_dist(O, P, 1); set_dist(P, Q, 2); set_dist(Q, R, 6); set_dist(R, S, 3); set_dist(S, T, 5); set_dist(T, U, 2); set_dist(U, V, 1); set_dist(V, W, 4); set_dist(W, X, 7); set_dist(X, Y, 2); set_dist(Y, Z, 3); set_dist(Z, A, 8); } int main(void) { for (int i = 0; i < DIM; i++) { for (int j = 0; j < DIM; j++) { g[i][j] = -1; } } init_graph(); printmat(g); int prev[DIM] = {0}; int dist[DIM] = {0}; dijkstra(g, prev, dist, A); for (int k = 0; k < DIM; k++) { printf("%c prev: %c\n", ntoch(k), ntoch(prev[k])); } path_reconstruct(prev, dist, A, Z); }