Ошибка (возможно) в реализации алгоритма Дейкстры

Задача: дан взвешенный ориентированный граф, все вершины пронумерованы начиная с нуля, нужно найти длину кратчайшего пути от вершины с номером 0 до выделенной вершины, кроме того, нужно восстановить сам путь.

Формат входных данных такой: в первой строке записаны три числа: K N M, K - номер выделенной вершины, N - количество вершин, M - количество рёбер. В следующих M строках записаны ребра в формате: from to weight, from - из какой вершины, to - в какую вершину, weight - вес ребра.

Для решения реализовал алгоритм Дейкстры, для восстановления пути в процессе работы вычисляются предшественники (массив p, в p[v] записан номер вершины, которая является предшественником вершины v). Расстояния, или, если точнее, оценки на расстояния от начальной вершины до всех остальных, хранятся в массиве d, в d[v] записано расстояние от вершины 0 до вершины v. Очередь (массив q), в которую записываются вершины, реализовал так: просто массив, индекс элемента - номер вершины, значение - 0 или 1, 0 означает, что для вершины еще не вычислен кратчайший путь, 1 означает обратное. Когда нам нужно вытащить из очереди элемент с наименьшим расстоянием, то мы находим такую вершину v, что d[v] минимально и при этом q[v] == 0. Соответственно, пока очередь не пуста, то есть есть вершины, для которых не вычислен кратчайший путь, то извлекаем вершину с минимальной оценкой расстояния, помечаем ее как обработанную и ослабляем все смежные с ней ребра. Решение не проходит один тест из восьми, неправильный ответ на тесте. Прошу подсказать, где в реализации (или, может быть, в теории) может быть ошибка. Не могу также исключить, что ошибка может быть и в тестирующей системе, но перед тем, как выяснять это вопрос, хотелось бы быть уверенным в том, что в решении нет ошибок.

#define _CRT_SECURE_NO_WARNINGS

#include<stdio.h>
#include<stdlib.h>

#define UNDEFINED -1

int *p, *d, *q;
int **matrix;

int **allocate_matrix(int n)
{
     int **matrix = (int**)malloc(n * sizeof(int*));

     if (!matrix)
     {
         return NULL;
     }

     for (int i = 0; i < n; i++)
     {
         matrix[i] = (int*)malloc(n * sizeof(int));

         if (!matrix[i])
         {
             for (int j = 0; j < i; j++)
             {
                 free(matrix[j]);
             }
             free(matrix);

             return NULL;
         }

         for (int j = 0; j < n; j++)
         {
             matrix[i][j] = UNDEFINED;
         }
     }

     return matrix;
 }

 void free_matrix(int **matrix, int size)
 {
     for (int i = 0; i < size; i++)
     {
         free(matrix[i]);
     }
     free(matrix);
 }     

 void print_matrix(int** matrix, int n)
 {
     for (int i = 0; i < n; i++)
     {
         for (int j = 0; j < n; j++)
         {
             printf("%d ", matrix[i][j]);
         }
         printf("\n");
     }
 }

 void relax(int u, int v)
 {
     if (d[v] > d[u] + matrix[u][v])
     {
         d[v] = d[u] + matrix[u][v];
         p[v] = u;
     }
 }

 int extract_min(int size)
 {
     int result = UNDEFINED;

     for (int i = 0; i < size; i++)
     {
         if (!q[i])
         {
             result = i;
             break;
         }
     }

     if (result == UNDEFINED)
     {
         return result;
     }

     for (int i = result + 1; i < size; i++)
     {
         if (!q[i] && d[i] < d[result])
         {
             result = i;
         }
     }

     return result;
 }

 void dijkstra(int s, int size)
 {
     int u;

     d[s] = 0;

     while (1)
     {
         u = extract_min(size);

         if (u == UNDEFINED)
         {
             break;
         }

         q[u] = 1;

         for (int i = 0; i < size; i++)
         {
             if (matrix[u][i] != UNDEFINED && !q[i])
             {
                 relax(u, i);
             }
         }
     }
 }

 void print_path(FILE *out, int size, int start, int current)
 {
     if (current == start)
     {
         fprintf(out, "%d ", current);
         return;
     }

     print_path(out, size, start, p[current]);
     fprintf(out, "%d ", current);
 }

 int main()
 {
     int target, points, paths, from, to;
     FILE *input = fopen("input.txt", "r");

     if (!input)
     {
         printf("Can't open input.txt");
         return -1;
     }

     fscanf(input, "%d %d %d", &target, &points, &paths);

     matrix = allocate_matrix(points);

     if (!matrix)
     {
         printf("Can't allocate matrix for graph.");
         return -1;
     }

     for (int i = 0; i < paths; i++)
     {
         fscanf(input, "%d %d", &from, &to);
         fscanf(input, "%d", &matrix[from][to]);
     }

     fclose(input);

     p = (int*)malloc(points * sizeof(int));
     d = (int*)malloc(points * sizeof(int));
     q = (int*)calloc(points, sizeof(int));

     if (!p || !d || !q)
     {
         printf("Can't allocate memory for p-array, d-array or q-array.");
         return -1;
     }

     for (int i = 0; i<points; i++)
     {
         p[i] = UNDEFINED;
         d[i] = INT_MAX;
     }

     dijkstra(0, points);

     FILE *output = fopen("output.txt", "w");
     if (!output)
     {
         printf("Can't open output.txt");
         return -1;
     }

     fprintf(output, "%d\n", d[target]);
     print_path(output, points, 0, target);

     fclose(output);

     free_matrix(matrix, points);
     free(p);
     free(q);
     free(d);

     return 0;
 }

Ответы (0 шт):