BUPT-homework/semester3/pset6/7-3-Shortest-Path.c

123 lines
2.5 KiB
C
Raw Normal View History

2022-11-19 20:33:35 +08:00
#include <stdio.h>
#include <stdlib.h>
#define SIZE 7
#define MAX 100
typedef struct node {
int index,
dist; // for the starting node, dist means shortest distance from start to
// here, for child nodes, dist means dist(parent, this)
struct node *next;
struct node *parent;
} node;
node *newNode(int index, int dist) {
node *new = malloc(sizeof(node));
new->index = index;
new->dist = dist;
new->next = NULL;
new->parent = NULL;
return new;
}
void appendEdge(node *src, int index, int dist) {
node *end = newNode(index, dist);
node *ptr = src;
while (ptr->next != NULL) {
ptr = ptr->next;
}
ptr->next = end;
}
node **makeGraph() {
node **g = malloc(sizeof(node *) * SIZE);
for (int i = 0; i < SIZE; i++) {
g[i] = newNode(i, MAX);
}
appendEdge(g[0], 1, 2);
appendEdge(g[0], 3, 1);
appendEdge(g[1], 3, 3);
appendEdge(g[1], 4, 10);
appendEdge(g[2], 0, 4);
appendEdge(g[2], 5, 5);
appendEdge(g[3], 2, 2);
appendEdge(g[3], 4, 2);
appendEdge(g[3], 5, 8);
appendEdge(g[3], 6, 4);
appendEdge(g[4], 6, 6);
appendEdge(g[6], 5, 1);
return g;
}
int getMinDistance(node **graph, int visited[]) {
int min = MAX, minIndex;
for (int i = 0; i < SIZE; i++) {
if (graph[i]->dist < min && visited[i] == 0) {
min = graph[i]->dist;
minIndex = i;
}
}
return minIndex;
}
void dijkstra(node **graph, int start) {
int visited[SIZE] = {};
for (int i = 0; i < SIZE; i++) {
int s = getMinDistance(graph, visited);
// printf("found start: %d\n", s);
visited[s] = 1;
node *ptr = graph[s]->next;
// update distance of unvisited nodes
while (ptr) {
if (visited[ptr->index] == 0 &&
graph[ptr->index]->dist > ptr->dist + graph[s]->dist) {
graph[ptr->index]->dist = ptr->dist + graph[s]->dist;
graph[ptr->index]->parent = graph[s];
// printf("Updated: %d, dist: %d\n", ptr->index,
// graph[ptr->index]->dist);
}
ptr = ptr->next;
}
}
}
int main(void) {
node **graph = makeGraph();
int start, end;
scanf("%d,%d", &start, &end);
start--;
end--;
// init the start's dist as 0
graph[start]->dist = 0;
dijkstra(graph, start);
if (graph[end]->parent == NULL) {
printf("-1");
} else {
int route[MAX];
int count = 0;
node *ptr = graph[end];
while (ptr) {
route[count++] = ptr->index;
ptr = ptr->parent;
}
for (int i = count - 1; i >= 0; i--) {
printf("%d,", route[i] + 1);
}
}
return 0;
}