Загрузка данных


"""
Задача 3 (Graf9).
Поиск всех маршрутов из города K1 в город K2 с ровно P пересадками.
Маршруты сортируются лексикографически и выводятся в текстовый файл.
Также генерируется файл graph_viz.dot для визуализации графа с подсветкой найденных путей.
"""

class RouteFinder:
    def __init__(self):
        self.n = 0
        self.matrix = []
        self.k1 = 0
        self.k2 = 0
        self.target_length = 0
        self.all_routes = []

    def _dfs(self, current_city, current_path, visited_cities):
        if len(current_path) == self.target_length:
            if current_city == self.k2:
                self.all_routes.append(list(current_path))
            return

        for neighbor in range(self.n):
            if self.matrix[current_city][neighbor] == 1 and neighbor not in visited_cities:
                visited_cities.add(neighbor)
                current_path.append(neighbor)
                
                self._dfs(neighbor, current_path, visited_cities)
                
                current_path.pop()
                visited_cities.remove(neighbor)

    def _generate_dot_file(self):
        successful_edges = set()
        for route in self.all_routes:
            for step in range(len(route) - 1):
                successful_edges.add((route[step], route[step + 1]))

        filename = "graph_viz.dot"
        with open(filename, 'w', encoding='utf-8') as f:
            f.write("digraph G {\n")
            f.write("    rankdir=LR;\n")
            
            for i in range(self.n):
                for j in range(self.n):
                    if self.matrix[i][j] == 1:
                        if (i, j) in successful_edges:
                            f.write(f'    {i + 1} -> {j + 1} [color="red", penwidth=2.0];\n')
                        else:
                            f.write(f'    {i + 1} -> {j + 1} [color="black", penwidth=1.0];\n')
            f.write("}\n")
        print(f"Файл визуализации {filename} успешно создан.")

    def start(self):
        file_in = input("Введите имя входного файла (например, graf9_in.txt): ")
        file_out = input("Введите имя выходного файла (например, graf9_out.txt): ")

        try:
            with open(file_in, 'r', encoding='utf-8') as f:
                lines = [line.strip() for line in f.readlines() if line.strip()]

            if not lines:
                raise ValueError("Файл пуст.")

            self.n = int(lines[0])
            if self.n > 15:
                raise ValueError("По условию задачи N <= 15.")

            self.matrix = []
            for i in range(1, self.n + 1):
                row = [int(x) for x in lines[i].split()]
                if len(row) != self.n:
                    raise ValueError(f"Размер матрицы не совпадает с N в строке {i}.")
                self.matrix.append(row)

            self.k1 = int(input(f"Введите номер города вылета K1 (от 1 до {self.n}): ")) - 1
            self.k2 = int(input(f"Введите номер города прилета K2 (от 1 до {self.n}): ")) - 1
            p_transfers = int(input("Введите количество пересадок P: "))

            if not (0 <= self.k1 < self.n) or not (0 <= self.k2 < self.n):
                raise ValueError("Номера городов вне допустимого диапазона.")

            self.target_length = p_transfers + 2
            self.all_routes = []

            visited = set([self.k1])
            self._dfs(self.k1, [self.k1], visited)
            
            self.all_routes.sort()

            self._generate_dot_file()

            with open(file_out, 'w', encoding='utf-8') as fout:
                if not self.all_routes:
                    fout.write("-1\n")
                    print(f"Маршрутов не найдено. В файл {file_out} записано -1.")
                else:
                    fout.write(f"{len(self.all_routes)}\n")
                    for route in self.all_routes:
                        formatted_route = [str(city + 1) for city in route]
                        fout.write(" ".join(formatted_route) + "\n")
                    print(f"Найдено маршрутов: {len(self.all_routes)}. Результат сохранен.")

        except FileNotFoundError:
            print("Ошибка: Входной файл не найден.")
        except Exception as e:
            print(f"Ошибка: {e}")

if __name__ == "__main__":
    app = RouteFinder()
    app.start()