baadgeorge

Untitled

Mar 21st, 2021 (edited)
91
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 9.92 KB | None | 0 0
  1. #include <iostream>
  2.  
  3. using namespace std;
  4.  
  5. const int n = 12; // кол-во вершин графа
  6.  
  7. // определение структуры для элемента стека
  8. struct cell
  9. {
  10.     int value; // значение в элемента
  11.     struct cell* next; // указатель на следующий элемент
  12. };
  13.  
  14. // определение имени list для типа cell
  15. typedef struct cell list;
  16.  
  17. // функция создания списка
  18. list* modStack(int val)
  19. {
  20.     list* newStack; // создание указателя на новый список
  21.     newStack = new list; // выделение памяти под новый список
  22.     newStack->value = val; // запись в ячейку значения элемента списка
  23.     newStack->next = NULL; // запись в ячейку указателя NULL на следующий элемент  
  24.     return(newStack);
  25. }
  26.  
  27. // функция вывода содержимого стека на экран
  28. void outputScreen(list* myStack)
  29. {
  30.     int pos = 0; // индекс позиции элемента в стеке
  31.     list* tmp = myStack; // указатель на стек
  32.     if (tmp == NULL)
  33.     {
  34.         std::cout << " ";
  35.     }
  36.     else
  37.     {
  38.         std::cout << "\n";
  39.         do
  40.         {
  41.             pos++; // увеличение индекса позиции на 1
  42.             std::cout << "-[" << pos << "]" << "(" << tmp->value << ")-"; // форматированный вывод элементов стека
  43.             tmp = tmp->next; //присвоение tmp указателя на следующий элемент стека
  44.         } while (tmp != NULL);
  45.     }
  46.     return;
  47. }
  48.  
  49.  
  50. // функция очистки стека
  51. void clearList(list** myStack)
  52. {
  53.     list* tmp = *myStack; // указатель на первый элемент стека
  54.     list* tmpNext = NULL; // указатель на следующий элемент стека
  55.     if (tmp == NULL)
  56.     {
  57.         std::cout << "Невозможно очистить пустой или не созданный стек\n";
  58.     }
  59.     else
  60.     {
  61.         do
  62.         {
  63.             tmpNext = tmp->next; // присвоение указателя на следующий элемент
  64.             delete tmp; // удаление указателя на текущий элемент
  65.             tmp = tmpNext; // присвоение текущему указателю указателя на следующий элемент
  66.         } while (tmp != NULL);
  67.         *myStack = NULL; // обнуление указателя на стек
  68.         //std::cout << "Стек успешно очищен\n";
  69.     }
  70.  
  71.     return;
  72. }
  73.  
  74.  
  75.  
  76. // функция извлечения элемента стека на заданной позиции
  77. int PopStack(list** myStack)
  78. {
  79.     int val = 0;
  80.     list* tmp = *myStack; // указатель на первый элемент стека
  81.     list* tmpPrev = NULL; // указатель на предыдущий элемент стека
  82.  
  83.     if (tmp == NULL) // указатель на первый элемент стека NULL
  84.     {
  85.         std::cout << "Невозможно извлечь элемент из пустого или не созданного стека\n";
  86.     }
  87.     else
  88.     {
  89.         if (tmp->next == NULL) // указатель на следующий элемент NULL
  90.         {
  91.             val = tmp->value;
  92.             clearList(myStack); // удаление всего стека из 1 элемента
  93.         }
  94.         else
  95.         {
  96.             do
  97.             {
  98.                 tmpPrev = tmp; // присвоение указателю на предыдущий элемент указателя на текущий элемент
  99.                 tmp = tmp->next; // присвоение указателю на текущий элемент указателя на следующий элемент
  100.             } while (tmp->next != NULL);
  101.             val = tmp->value;
  102.  
  103.             tmpPrev->next = NULL; // указателю на следующий элемент для i-1 элемента присвоить указатель NULL
  104.             delete tmp; // удаление указателя на извлеченный элемент
  105.         }
  106.     }
  107.     return val;
  108. }
  109.  
  110. // функция добавления элемента в стек
  111. void PushStack(list** myStack, int val)
  112. {
  113.     list* tmp = *myStack; // указатель на первый элемент стека
  114.     list* tmpPrev = NULL; // указатель на предыдущий элемент стека
  115.  
  116.  
  117.     if (tmp == NULL)
  118.     {
  119.         *myStack = modStack(val); // создание стека с текущим элементом
  120.         //std::cout << "Новый стек успешно создан\n";
  121.     }
  122.     else
  123.     {
  124.         do
  125.         {
  126.             tmpPrev = tmp; // присвоение указателю на предыдущий элемент указателя на текущий элемент
  127.             tmp = tmp->next; // присвоение указателю на текущий элемент указателя на следующий элемент
  128.         } while (tmp != NULL); // указатель на текущий элемент NULL
  129.  
  130.         tmpPrev->next = modStack(val); // присвоение указателю предыдущего элемента на следующий элемент указателя на введенный элемент
  131.     }
  132.  
  133.     //std::cout << "Новый элемент со значением " << val << " добавлен в конец стека\n";
  134.     return;
  135. }
  136.  
  137.  
  138. // функция топологической сортировки графа
  139. void topological_s(int(*matrix)[n], int inf, list** next, int** sorted)
  140. {
  141.  
  142.     int i, j, k; // индексные переменные
  143.     int u = 0; // номер рассматриваемой вершины
  144.     int in_degree[n] = { 0 }; // массив входящих степеней вершин
  145.  
  146.     // заполнение массива входящих степеней вершин
  147.     for (i = 0; i < n; i++)
  148.     {
  149.         for (j = 0; j < n; j++)
  150.         {
  151.             if (matrix[i][j] != inf)
  152.             {
  153.                 in_degree[j]++;
  154.             }
  155.         }
  156.     }
  157.  
  158.     for (i = 0; i < n; i++)
  159.     {
  160.         if (in_degree[i] == 0)
  161.         {
  162.             PushStack(next, i);
  163.         }
  164.     }
  165.  
  166.     k = 0;
  167.     // пока существую вершины с входящей степенью 0
  168.     while (*next != NULL)
  169.     {
  170.         u = PopStack(next); // выбор вершины для обработки из начала списка next
  171.         (*sorted)[k++] = u; // запись вершины u в список sorted
  172.  
  173.         // поиск вершин с входящей степенью 0 после ослабления графа
  174.         for (i = 0; i < n; i++)
  175.         {
  176.             if (matrix[u][i] != inf)
  177.             {
  178.                 in_degree[i]--;
  179.                 if (in_degree[i] == 0)
  180.                 {
  181.                     PushStack(next, i);
  182.                 }
  183.             }
  184.         }
  185.  
  186.     }
  187.     return;
  188. }
  189.  
  190.  
  191. // поиск кратчайших путей
  192. int* dag_shortest_path(int(*matrix)[n], int s, int inf, int* sorted)
  193. {
  194.     int* shortest = new int[n]; // массив весов кратчайших путей
  195.     int* pred = new int[n]; // массив предыдущих вершин
  196.     int i, j, k; // индексные переменные
  197.  
  198.     // инициализация массива shortest и pred
  199.     for (i = 0; i < n; i++)
  200.     {
  201.         pred[i] = -1;
  202.         if (i != s) shortest[i] = inf;
  203.         else shortest[i] = 0;
  204.     }
  205.  
  206.     // вычисление кратчайших путей из заданной вершины s
  207.     for (i = 0; i < n; i++)
  208.     {
  209.         for (j = 0; j < n; j++)
  210.         {
  211.             if (matrix[sorted[i]][j] != inf) // если путь существует
  212.             {
  213.                 if ((shortest[sorted[i]] + matrix[sorted[i]][j]) < shortest[j]) // новый вес пути меньше текущего
  214.                 {
  215.                     shortest[j] = shortest[sorted[i]] + matrix[sorted[i]][j]; // присвоить новый вес кратчайшего пути
  216.                     pred[j] = sorted[i];
  217.                 }
  218.             }
  219.         }
  220.        
  221.     }
  222.     return shortest;
  223. }
  224.  
  225. int main()
  226. {
  227.     setlocale(LC_ALL, "RUS");
  228.  
  229.     int s = 0; // вершина для поиска критического пути
  230.     int inf = 10000; // бесконечно большая величина
  231.     int* shrt; // указатель на массив кратчайших путей
  232.     int i = 0; // счетчик
  233.     int* sorted = new int[n] { 0 };
  234.     list* next = NULL;
  235.  
  236.  
  237.     int matrix[][n] =
  238.     {
  239.     { inf, 3, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf },
  240.     { inf, inf, 4, inf, inf, inf, inf, inf, inf, inf, inf, inf },
  241.     { inf, inf, inf, 15, 6, inf, inf, inf, inf, inf, inf, inf },
  242.     { inf, inf, inf, inf, inf, 34, inf, inf, inf, inf, inf, inf },
  243.     { inf, inf, inf, inf, inf, 9, inf, inf, inf, inf, inf, inf },
  244.     { inf, inf, inf, inf, inf, inf, 8, inf, inf, inf, inf, inf },
  245.     { inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, 19, inf },
  246.     { inf, inf, inf, inf, inf, inf, inf, inf, 12, inf, inf, inf },
  247.     { inf, inf, inf, inf, 11, inf, inf, inf, inf, inf, inf, inf },
  248.     { inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, 11, inf },
  249.     { inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, 10 },
  250.     { inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf }
  251.     };
  252.  
  253.     cout << "Введите начальную вершину " << endl;
  254.     cin >> s; // исходная вершина
  255.  
  256.     topological_s(matrix, inf, &next, &sorted);
  257.  
  258.     // форматированный вывод массива, возвращаемого топологической сортировкой
  259.     cout << "\n\nЛинейный список вершин графа возвращаемый топологической сортировкой: "<<endl;
  260.     for (i = 0; i < n; i++)
  261.     {
  262.         cout << sorted[i] << " ";
  263.     }
  264.  
  265.     shrt = dag_shortest_path(matrix, s, inf, sorted);// массив кратчайших путей из вершины s
  266.  
  267.     cout << "\n\nСписок кратчайших путей из вершины " << s << " :" << endl;
  268.  
  269.     // форматированный вывод массива кратчайших путей
  270.     for (i = 0; i < n; i++)
  271.     {
  272.         if (shrt[i] == inf)
  273.         {
  274.             cout << "(" << s << ", " << i << ") не существует  " << endl;
  275.         }
  276.         else
  277.         {
  278.             cout << "(" << s << ", " << i << ") = " << shrt[i] << endl;
  279.         }
  280.     }
  281.     cout << endl;
  282.  
  283.     system("pause");
  284.  
  285. }
Add Comment
Please, Sign In to add comment