/* As we all know that, in routing protocol OSPF, algorithm Dijkstra is used to calculate the shortest path. * The following codes show us the basic operation in Dijkstra. But there are still many faults. * For example, the "path" variable cannot shows us the vertex sequence and if there are more than one paths * which have the same cost, the variable "distance" can only show us the last one ...... * version: 0.1; by: double; date: 2009-07-12. */ #include "/usr/c/head.h" #define MAX 20 #define INT_MAX ((int)(~0U>>1)) #define SCAN_INT(x, y); if (scanf("%d", &x) != EOF) while ((y = getchar()) != '/n' && y != EOF) {;} #define SCAN_CHAR(x, y); if (scanf("%c", &x) != EOF) while ((y = getchar()) != '/n' && y != EOF) {;} typedef int arc_type; typedef char vex_type; typedef struct matrix_graph { vex_type vexs[MAX]; arc_type arcs[MAX][MAX]; int vexnum, arcnum; }matrix_graph; matrix_graph G; int final[MAX]; int distance[MAX]; int path[MAX][MAX]; int locate_vex(matrix_graph G, vex_type v) { int i; for (i = 0; i < G.vexnum; ++i) if (G.vexs[i] == v) return i; return -1; } status init_graph(matrix_graph *G) { int temp, i, j, p1, p2; vex_type v1, v2; printf("Input the vexnum:"); SCAN_INT(G->vexnum, temp); for (i = 0; i < G->vexnum; ++i) { printf("No.%d:", i + 1); SCAN_CHAR(G->vexs[i], temp); for (j = 0; j < G->vexnum; ++j) G->arcs[i][j] = INT_MAX; } printf("Input the arcnum:"); SCAN_INT(G->arcnum, temp); for (i = 0; i < G->arcnum; ++i) { printf("No.%d, v1:", i + 1); SCAN_CHAR(v1, temp); printf("No.%d, v2:", i + 1); SCAN_CHAR(v2, temp); p1 = locate_vex(*G, v1); if (p1 == -1) { printf("v1 = %c out of range!/n"); exit(ERROR); } p2 = locate_vex(*G, v2); if (p2 == -1) { printf("v2 = %c out of range!/n"); exit(ERROR); } printf("Weight:"); SCAN_INT(G->arcs[p1][p2], temp); } return OK; } status print_graph(matrix_graph G) { int i, j; printf("vextex are:/n"); for (i = 0; i < G.vexnum; ++i) printf("%c/t", G.vexs[i]); printf("arcs are:/n"); for (i = 0; i < G.vexnum; ++i) { for (j = 0; j < G.vexnum; ++j) printf("%d/t", G.arcs[i][j]); printf("/n/n/n/n"); } return OK; } status dijkstra(vex_type ch) { int k, i, w, j, min, v; k = locate_vex(G, ch); for (i = 0; i < G.vexnum; ++i) { distance[i] = G.arcs[k][i]; final[i] = FALSE; for (w = 0; w < G.vexnum; ++w) path[k][w] = FALSE; if (distance[i] < INT_MAX) { path[i][i] = TRUE; path[i][k] = TRUE; } } distance[k] = 0; final[k] = TRUE; for (i = 1; i < G.vexnum; ++i) { min = INT_MAX; for (w = 0; w < G.vexnum; ++w) if (!final[w] && distance[w] < min) { v = w; min = distance[w]; } final[v] = TRUE; for (w = 0; w < G.vexnum; ++w) if (!final[w] && min + G.arcs[v][w] > 0 && min + G.arcs[v][w] < distance[w]) { distance[w] = min + G.arcs[v][w]; for (j = 0; j < G.vexnum; ++j) path[w][j] = path[v][j]; path[w][w] = TRUE; } } return OK; } int main(void) { vex_type ch; int temp, i, j; init_graph(&G); printf("Graph initilized OK!/n"); printf("Input the starting vertex:"); SCAN_CHAR(ch, temp); dijkstra(ch); for (i = 0; i < G.vexnum; ++i) printf("%d/t", distance[i]); printf("/n/n"); for (i = 0; i < G.vexnum; ++i) { for (j = 0; j < G.vexnum; ++j) printf("%3d", path[i][j]); printf("/n/n"); } return 0; }