public static Graph <VisVertex> GetMstPrim(Graph <VisVertex> graph)
        {
            if (!graph.IsConnected)
            {
                throw new Exception("Граф не связен");
            }
            Random rnd = new Random();

            bool[] inMST = new bool[graph.Order];
            //Создаем логический массив для проверки вхождения вершин в МОД
            List <Vertex <VisVertex> > verticesMST = graph.VerticesClone;
            //Создаем список вершин МОД
            List <Edge <VisVertex> > edgesMST = new List <Edge <VisVertex> >();
            //Создаем список ребер МОД
            var adjVertexSortLists = GetAdjLists(graph);
            //Создаем сортированные списки смежности для вершин графа
            var adjVertexSortListMST = new AdjVertexSortedList();
            //Создаем пустой сортированный список смежности для всего МОД
            int firsrVertex = rnd.Next(0, graph.Order);

            //Выбираем случайную вершину для начала построения МОД
            inMST[firsrVertex] = true;
            //Отмечаем произвольную вершину, как включенную в МОД
            adjVertexSortListMST = adjVertexSortListMST.Union(
                adjVertexSortLists[firsrVertex], inMST);
            //Объединяем список смежности МОД и список смежности выбраной вершины
            //(при объединении сортировка поддерживается)
            for (int i = 0; i < graph.Order - 1; i++)
            //Цикл для построения МОД, шагов по количеству вершин - 1
            {
                Edge <VisVertex> edge2Add = adjVertexSortListMST.ExtractMinWeightEdge();
                //выбираем из списка смежности МОД ребро минимального веса
                AddEdge(edge2Add, verticesMST, edgesMST);
                //Добавляем ребро мнимального веса в МОД
                inMST[edge2Add.V2Id] = true;
                //Отмечаем присоединенную вершину, как включенную в МОД
                adjVertexSortListMST = adjVertexSortListMST.Union(
                    adjVertexSortLists[edge2Add.V2Id], inMST);
                //Объединяем списки смежности МОД и последней добавленной вершины
                //(при этом ребра внутри МОД удаляются)
            }
            if (edgesMST.Count != graph.Order - 1)
            {
                throw new Exception("Ошибка МОД не найдено");
            }
            return(new Graph <VisVertex>(verticesMST, edgesMST));
        }
        public async void PrimsAlgorithmVisAsync(Color mstColor, bool startFrom0)
        {
            if (!graph.IsConnected)
            {
                visualisator.Print("Остовное дерево не может быть построено. Граф не связен!");
                visualisator.ApEndLog("Остовное дерево не может быть построено. Граф не связен!");
                return;
            }
            form.BlockTabControl();
            int mstWeight = 0;

            bool[] inMST = new bool[graph.Order];
            //Создаем логический массив для проверки вхождения вершин в МОД
            List <Edge <VisVertex> > edgesMST = new List <Edge <VisVertex> >();
            //Создаем список ребер МОД
            var adjVertexSortLists = GetAdjLists(graph);
            //Создаем сортированные списки смежности для вершин графа
            var adjVertexSortListMST = new AdjVertexSortedList();
            //Создаем пустой сортированный список смежности для всего МОД
            int firsrVertex = startFrom0 ? 0 : rnd.Next(0, graph.Order);

            //Выбираем случайную вершину для начала построения МОД
            inMST[firsrVertex] = true;
            //Отмечаем произвольную вершину, как включенную в МОД

            visualisator.SetVertexColor(firsrVertex, mstColor);
            visualisator.Print(startFrom0 ?
                               "Начиная с нулевой вершины" : "Начальная вершина выбрана произвольно");
            visualisator.ApEndLog(startFrom0 ?
                                  "Начиная с нулевой вершины" : "Произвольный выбор начальной вершины МОД.");
            await Task.Delay(SleepInterval);

            adjVertexSortListMST = adjVertexSortListMST.Union(
                adjVertexSortLists[firsrVertex], inMST);
            //Объединяем список смежности МОД и список смежности выбраной вершины
            //(при объединении сортировка поддерживается)
            for (int i = 0; i < graph.Order - 1; i++)
            //Цикл для построения МОД, шагов по количеству вершин - 1
            {
                Edge <VisVertex> edge2Add = adjVertexSortListMST.ExtractMinWeightEdge();
                //выбираем из списка смежности МОД ребро минимального веса
                edgesMST.Add(edge2Add);
                //Добавляем ребро мнимального веса в МОД
                inMST[edge2Add.V2Id] = true;
                //Отмечаем присоединенную вершину, как включенную в МОД
                mstWeight           += edge2Add.Weight;
                adjVertexSortListMST = adjVertexSortListMST.Union(
                    adjVertexSortLists[edge2Add.V2Id], inMST);
                //Объединяем списки смежности МОД и последней добавленной вершины
                //(при этом ребра внутри МОД удаляются)

                visualisator.ApEndLog($"Шаг {i + 1}. Выбираем ребро минимального веса, " +
                                      $"соединяющее вершину внутри и вне МОД -  {edge2Add}");
                visualisator.SetEdgeColor(edge2Add, mstColor);
                visualisator.SetVertexColor(edge2Add.V2Id, mstColor);
                visualisator.Print($"Добавление к МОД смежного ребра минимального веса. " +
                                   $"Всего ребер {edgesMST.Count}. Общий вес {mstWeight}.");
                visualisator.PrintDataStructuresPrim(adjVertexSortLists, adjVertexSortListMST);
                await Task.Delay(SleepInterval);
            }
            if (edgesMST.Count != graph.Order - 1)
            {
                throw new Exception("Ошибка МОД не найдено");
            }
            else
            {
                visualisator.Print(
                    $"Минимальное остовное дерево построено. Общий вес {mstWeight}.");
                visualisator.ApEndLog(
                    $"Минимальное остовное дерево построено. Общий вес {mstWeight}.");
                visualisator.PrintDataStructuresPrim(adjVertexSortLists, adjVertexSortListMST);
            }
            form.UnBlockTabControl();
        }