#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#define MAX_NODES 5
// Edge structure
typedef struct Edge {
int to;
int weight;
struct Edge* next;
} Edge;
// Graph structure: adjacency list
typedef struct Graph {
Edge* edges[MAX_NODES];
} Graph;
// Add edge to graph
void add_edge(Graph* g, int from, int to, int weight) {
Edge* e = (Edge*)malloc(sizeof(Edge));
e->to = to;
e->weight = weight;
e->next = g->edges[from];
g->edges[from] = e;
}
// Stack for topological sort
typedef struct Stack {
int data[MAX_NODES];
int top;
} Stack;
void push(Stack* s, int val) {
s->data[++(s->top)] = val;
}
int pop(Stack* s) {
return s->data[(s->top)--];
}
// DFS for topological sort
void dfs(Graph* g, int node, int visited[], Stack* stack) {
visited[node] = 1;
for (Edge* e = g->edges[node]; e != NULL; e = e->next) {
if (!visited[e->to]) {
dfs(g, e->to, visited, stack);
}
}
push(stack, node); // push after visiting all descendants
}
// Find topological order
void topological_sort(Graph* g, int order[]) {
int visited[MAX_NODES] = {0};
Stack stack;
stack.top = -1;
for (int i = 0; i < MAX_NODES; i++) {
if (!visited[i]) {
dfs(g, i, visited, &stack);
}
}
// Pop from stack to get order
for (int i = 0; i < MAX_NODES; i++) {
order[i] = pop(&stack);
}
}
// Shortest path in DAG using topological order
void shortest_path_dag(Graph* g, int start, int dist[]) {
int order[MAX_NODES];
topological_sort(g, order);
// Initialize distances
for (int i = 0; i < MAX_NODES; i++) {
dist[i] = INT_MAX;
}
dist[start] = 0;
// Relax edges in topological order
for (int i = 0; i < MAX_NODES; i++) {
int u = order[i];
if (dist[u] != INT_MAX) {
for (Edge* e = g->edges[u]; e != NULL; e = e->next) {
int v = e->to;
int w = e->weight;
if (dist[u] + w < dist[v]) {
dist[v] = dist[u] + w;
}
}
}
}
}
int main() {
Graph g = {0};
add_edge(&g, 0, 1, 2);
add_edge(&g, 0, 2, 4);
add_edge(&g, 1, 2, 1);
add_edge(&g, 1, 3, 7);
add_edge(&g, 2, 4, 3);
add_edge(&g, 3, 4, 1);
int dist[MAX_NODES];
shortest_path_dag(&g, 0, dist);
for (int i = 0; i < MAX_NODES; i++) {
if (dist[i] == INT_MAX) {
printf("Node %d: unreachable\n", i);
} else {
printf("Node %d: %d\n", i, dist[i]);
}
}
return 0;
}
topological_sort(g, order);
Get nodes in order so all edges go forward
Set start node distance to zero
for (int i = 0; i < MAX_NODES; i++) { int u = order[i]; if (dist[u] != INT_MAX) { for (Edge* e = g->edges[u]; e != NULL; e = e->next) { int v = e->to; int w = e->weight; if (dist[u] + w < dist[v]) { dist[v] = dist[u] + w; } } } }
Relax edges from each node in topological order to update shortest distances
Node 0: 0
Node 1: 2
Node 2: 3
Node 3: 9
Node 4: 6