En un grafo no ponderado todas las aristas cuestan lo mismo: un paso. El camino mínimo entre dos vértices es el que usa la menor cantidad de aristas. Para este caso, el algoritmo ideal es la BFS (Breadth-First Search).
Simulador de camino mínimo en un grafo
Cuando todos los pesos valen 1, no hace falta Dijkstra: BFS recorre por niveles y alcanza primero las distancias mínimas (Dijkstra se verá más adelante para grafos ponderados).
Ejemplo: grafo A → B → C → D. Niveles: A (0), B (1), C (2), D (3). Distancia mínima A-D = 3 aristas. Camino: A → B → C → D.
Se usa un arreglo dist[] inicializado en -1 y dist[origen] = 0. Al descubrir un vecino v desde u:
dist[v] = dist[u] + 1
Así se generan automáticamente las distancias en saltos.
Para obtener el camino exacto se guarda padre[] (o prev[]): al descubrir v desde u, asignamos padre[v] = u. Luego:
camino = []
v = destino
mientras v != -1:
camino.push(v)
v = padre[v]
invertir(camino)
Ejemplo: padre[D]=C, padre[C]=B, padre[B]=A, padre[A]=-1. Camino reconstruido: A → B → C → D.
Implementación de BFS con distancias y reconstrucción del camino usando padre[], con un grafo cargado en código (sin entrada por teclado).
#include <stdio.h>
#include <stdlib.h>
typedef struct Edge {
int to;
struct Edge *next;
} Edge;
typedef struct {
int n;
Edge **adj;
} Graph;
Graph crearGrafo(int n) {
Graph g;
g.n = n;
g.adj = calloc(n, sizeof(Edge *));
return g;
}
void agregarAristaNoDirigida(Graph *g, int u, int v) {
Edge *a = malloc(sizeof(Edge));
a->to = v;
a->next = g->adj[u];
g->adj[u] = a;
Edge *b = malloc(sizeof(Edge));
b->to = u;
b->next = g->adj[v];
g->adj[v] = b;
}
void bfsDistancias(const Graph *g, int origen, int *dist, int *padre) {
int *cola = malloc(g->n * sizeof(int));
int ini = 0, fin = 0;
for (int i = 0; i < g->n; i++) {
dist[i] = -1;
padre[i] = -1;
}
dist[origen] = 0;
padre[origen] = origen;
cola[fin++] = origen;
while (ini < fin) {
int u = cola[ini++];
for (Edge *e = g->adj[u]; e; e = e->next) {
int v = e->to;
if (dist[v] == -1) {
dist[v] = dist[u] + 1;
padre[v] = u;
cola[fin++] = v;
}
}
}
free(cola);
}
void imprimirCamino(int destino, const int *padre) {
int pila[128];
int tope = 0;
int v = destino;
while (v != -1 && tope < 128) {
pila[tope++] = v;
if (padre[v] == v) break;
v = padre[v];
}
for (int i = tope - 1; i >= 0; i--) {
printf("%d%s", pila[i], (i == 0) ? "\n" : " -> ");
}
}
int main(void) {
Graph g = crearGrafo(6);
agregarAristaNoDirigida(&g, 0, 1);
agregarAristaNoDirigida(&g, 0, 2);
agregarAristaNoDirigida(&g, 1, 3);
agregarAristaNoDirigida(&g, 1, 4);
agregarAristaNoDirigida(&g, 2, 5);
int origen = 0, destino = 5;
int *dist = malloc(g.n * sizeof(int));
int *padre = malloc(g.n * sizeof(int));
bfsDistancias(&g, origen, dist, padre);
printf("Distancias minimas desde %d:\n", origen);
for (int i = 0; i < g.n; i++) {
printf("Nodo %d: %d\n", i, dist[i]);
}
printf("\nCamino minimo de %d a %d: ", origen, destino);
if (dist[destino] == -1) {
printf("no existe\n");
} else {
imprimirCamino(destino, padre);
}
free(dist);
free(padre);
free(g.adj);
return 0;
}