Методи за програмиране

Задача 4. Топологично сортиране на върховете на графа

Главна информация

Задачата се състои от две части, първата от които е задължителна, втората се изпълнява за получаване на оценка „отличен“.

Двоично отношениевърху множество A е подмножество на декартовото произведение M x M, т.е. някакво множество от подредени двойки, всеки елемент от които е елемент от множеството A . Например релацията > (по-голямо от) е двоична релация в множеството и съдържа двойки (2, 1), (3, 1), (4, 1), (3, 2), (4, 2), (4, 3) . Ще кажем, че твърдението a R b е вярно, ако двойката (a, b) принадлежи на двоичното отношение R .

Нека някакво бинарно отношение R е дадено върху крайно множество A . Задачата на топологичното сортиране е да подреди елементите на множеството A в последователността a1, a2, . aN, така че за всяка двойка (ai, aj), така че ai R aj е вярно, условието i е изпълнено.

Ако представим връзката като насочен граф (елементите на множеството са върхове, ръбът от връх a до връх b съществува тогава и само ако a R b е вярно), тогава проблемът може да се формулира по следния начин: избройте върховете на графа в такъв ред, че за всяко ребро на графа началният му връх да е посочен преди последния. Фигурата отляво показва оригиналния граф, отдясно неговите върхове са изброени в необходимия ред.

методи

Ето пример за използване на топологично сортиране: да предположим, че има редица задачи, някои от които не могат да бъдат изпълнени, докато не бъдат изпълнени някои други задачи. Този набор от задачи е представен като насочен граф и в резултат на топологично сортиране на върховете на този граф,последователност от задачи, която отговаря на всички условия.

Ясно е, че е възможно да се извърши топологично сортиране не във всеки граф, а само в такъв, в който няма цикли. Алгоритъмът, описан по-долу, извършва топологично сортиране на граф без цикли.

  1. Маркираме всички върхове на графа като неизползвани.
  2. Търсим неизползван връх, който не включва никакви ребра (има само нули в съответната колона на матрицата на съседство). Ако няма такъв връх, тогава или сме преминали през всички върхове (топологичното сортиране е приключило), или има цикъл в графа (топологичното сортиране е невъзможно).
  3. Маркираме намерения връх като използван, отпечатваме неговия номер.
  4. Премахваме от графиката всички ръбове с начало в този връх (съответният ред на матрицата на съседство е настроен на нула).
  5. Да преминем към стъпка 2.

За да ускорите алгоритъма, можете да съхраните в масива броя на ръбовете, включени в даден връх, и да актуализирате този номер, когато изтривате всеки ръб.

Формулиране на задача

а. Внедряване върху матрици на съседство.

Входният файл input.txt съдържа графика като списък от ребра. Прочетете го в матрица на съседство (двумерен масив, чийто елемент (i, j) е равен на 1, ако графиката има ребро от връх i до връх j, и 0 в противен случай) и извършете топологично сортиране на тази графика. Изведете резултата (последователност от върхове или съобщение за наличието на цикъл в графиката) във файла output.txt.

b. *Внедряване на списъци за съседство.

Същата задача, но съхранявайте графиката като списък на съседство (за всеки връх се съхранява списък от върхове, който има ребро от този връх).