#include #include #include /* O(n) - алгоритм Тарьяна */ int* solve(int** massiv, int n); void dfs(int** massiv, int size, int* paint, int vertex, int* problem, int* len); int main(){ int n; scanf("%d", &n); int **adj = (int**)calloc(n, sizeof(int*)); for (int i = 0; i < n; i++) { adj[i] = (int*)calloc(n, sizeof(int)); } for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { scanf("%d", &adj[i][j]); } } int *res = solve(adj, n); for (int i = 0; i < n; ++i) { printf("%d ", res[i]); } /* Освобождаем память */ for (int i = 0; i < n; i++) { free(adj[i]); } free(adj); free(res); } int* solve(int** adj, int n) { int* res = (int*)calloc(n, sizeof(int)); /* Список раскрасок вершин, 0 - белый, 1 - серый, 2 - черный */ int* paint = (int*)calloc(n, sizeof(int)); int len = n - 1; for (int i = 0; i < n; i++) { if (paint[i] == 0) { dfs(adj, n, paint, i, res, &len); } /* Если нашлась серая вершина на данном шаге, то граф цикличен */ else if (paint[i] == 1) { printf("Граф цикличен, решения не существует:\n"); assert(0); } } free(paint); return res; } void dfs(int **adj, int size, int* paint, int vertex, int* res, int* len) { if (paint[vertex] == 0) { /* Красим белую вершину в серую */ paint[vertex] = 1; /* вызываем поиск в глубину для каждой вершины, в которую можем дойти из данной, рекурсивно */ for (int i = 0; i < size; i++) { if (adj[vertex][i] == 1) { dfs(adj, size, paint, i, res, len); } } /* Заносим вершину в список для вывода */ res[(*len)--] = vertex; /* Красим вершину в черный, она обработана */ paint[vertex] = 2; } /* Если нашлась серая вершина - граф цикличен */ else if (paint[vertex] == 1) { printf("Граф цикличен, решения не существует:\n"); assert(0); } }