Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- // Чтение графа происходит из файла in.txt, который устроен следующим образом
- // Сначала идут три целых числа: n - количество вершин, a - пункт отправления, b - пункт назначения
- // Затем идет n строк по n целых чисел в каждой строке - матрица смежности графа
- // Запись осуществляется в файл out.txt
- unsigned const int MAX_SIZE = 100; // Максимальное количество вершин
- void read_graph(int * graph, int * n, int * a, int * b, const char * filename); // Чтение входных данных
- int search_path(int * graph, int n, int a, int b, int * path, int * path_len); // Поиск пути
- void write_path(int * path, int n, const char * filename); // Запись выходных данных
- int pop(int * queue, int * n); // Вынуть верхний элемент из очереди
- void push(int * queue, int * n, int value); // Добавить в конец очереди новый элемент
- int main(){
- int graph[MAX_SIZE][MAX_SIZE]; // Матрица смежности графа
- int n, a, b; // n - количество вершин. Из вершины a в вершину b ищем минимальный путь
- int path[MAX_SIZE]; // Путь
- int path_len; // Его длина
- int * ptr_graph = (int*)graph; // Указатель на матрицу смежности
- read_graph(ptr_graph, &n, &a, &b, "in.txt"); // Считываем граф
- if (search_path(ptr_graph, n, a, b, path, &path_len)) // Ищем путь
- printf("The path has been successfully found!\n");
- else
- printf("The right path does not exist!\n");
- write_path(path, path_len, "out.txt"); // Записываем путь в файл
- return 0;
- }
- void read_graph(int * graph, int * n, int * a, int * b, const char * filename){
- // Открываем файл для чтения:
- FILE *fp;
- fp = fopen(filename, "r");
- // Считываем оттуда количество вершин, вершину a и вершину b:
- fscanf(fp, "%d %d %d", n, a, b);
- // Считываем оттуда матрицу смежности графа:
- int i, j;
- for (i = 0; i < *n; i++)
- for (j = 0; j < *n; j++)
- fscanf(fp, "%d ", graph+(*n)*i+j);
- // Закрываем файл
- fclose(fp);
- }
- int pop(int * queue, int * n){
- // Вынимаем элемент из очереди
- int t = queue[0], i;
- *n -= 1;
- for(i = 0; i < *n; i++)
- queue[i] = queue[i+1];
- return t;
- }
- void push(int * queue, int * n, int value){
- // Кладем новый элемент в очередь
- queue[*n] = value;
- *n += 1;
- }
- int search_path(int * graph, int n, int a, int b, int * path, int * path_len){
- // Ищем минимальный путь поиском в ширину
- *path_len = 0; // Длина пути
- int visited[MAX_SIZE], q[MAX_SIZE]; // Посещенные вершины и очередь для посещения вершин
- int q_len = 0, i, j; // Длина очереди и счетчики циклов
- for(i = 0; i < n; i++) // Обнуляем массив посещенных вершин
- visited[i] = -1;
- // Кидаем стартовую вершину в очередь и запоминаем, что мы ее посетили:
- push(q, &q_len, a);
- visited[a] = a;
- // Пока мы не обработали необходимые вершины, обрабатываем их:
- while (q_len > 0) {
- // Вынимаем очередную вершину:
- const int t = pop(q, &q_len);
- // Если мы достигли необходимой вершины, то логично бы прекратить поиск
- if (t == b) break;
- // В цикле кидаем в очередь все посещенные смежные с вершиной t вершины:
- for (i = 0; i < n; i++)
- // ЕСЛИ существует ребро t -> i и ЕСЛИ мы по нему еще не прошли:
- if (*(graph+t*n+i) && visited[i] == -1 ) {
- visited[i] = t; // Сохраняем в visited[i] вершину t, из которой мы пришли в вершину i
- push(q, &q_len, i); // Кидаем вершину i в очередь обработки
- }
- }
- // Возвращаемся из вершины b в вершину a по тому пути , который мы запомнили в visited
- while ( b != a && visited[b] != -1 ){
- push(path, path_len, b); // Кидаем вершины в вектор пути
- b = visited[b];
- }
- // Если нам удалось дойти до стартовой вершины , то кидаем ее в наш путь
- if ( b == a ) push(path, path_len, a);
- // Приведение пути к нормальному виду (переворачиваем его)
- for (i = 0, j = *path_len-1; i < j; ++i,--j){
- int temp = path[i];
- path[i] = path[j];
- path[j] = temp;
- }
- return *path_len; // Возвращаем длину найденного пути
- }
- void write_path(int * path, int n, const char * filename){
- // Запись пути в файл
- FILE *fp;
- fp = fopen(filename, "w");
- int i;
- for (i = 0; i < n; i++)
- fprintf(fp, "%d ", path[i]);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement