Xisepe

lab7

Feb 20th, 2022
76
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.69 KB | None | 0 0
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <memory.h>
  4.  
  5. enum InitializeState {
  6.     OK, BAD_NUMBER_OF_VERTICES, BAD_NUMBER_OF_EDGES, BAD_VERTEX, BAD_NUMBER_OF_LINES_BEFORE, BAD_NUMBER_OF_LINES_AFTER
  7. };
  8.  
  9. enum SortState {
  10.     SORTED, IMPOSSIBLE_TO_SORT
  11. };
  12.  
  13. enum Colors {
  14.     WHITE = 1,
  15.     GREY = 2,
  16.     BLACK = 3
  17. };
  18.  
  19. enum InitializeState checkVertex(const int vertex, const int N) {
  20.     if (vertex <= 0 || vertex > N)
  21.         return BAD_VERTEX;
  22.     return OK;
  23. }
  24.  
  25. int getBytePosition(const int vertex) {
  26.     return (vertex - 1) / 8 + 1;
  27. }
  28.  
  29. int getVertexInBitRepresentation(const int vertex) {
  30.     return 1 << (7 - (vertex % 8));
  31. }
  32.  
  33. void addVertexToMatrix(char **matrix, const int from_vertex, const int to_vertex) {
  34.     if (matrix == NULL)
  35.         return;
  36.     matrix[from_vertex - 1][getBytePosition(to_vertex)] |= getVertexInBitRepresentation(to_vertex);
  37. }
  38.  
  39. int isVertexInMatrix(char **matrix, const int from_vertex, const int to_vertex) {
  40.     return matrix[from_vertex - 1][getBytePosition(to_vertex)] & getVertexInBitRepresentation(to_vertex);
  41. }
  42.  
  43. char **createMatrix(const int N) {
  44.     char **arr = (char **) calloc(N, sizeof(char *));
  45.     for (int i = 0; i < N; ++i) {
  46.         arr[i] = calloc(getBytePosition(N) + 1, sizeof(char));
  47.         arr[i][0] = WHITE;
  48.     }
  49.     return arr;
  50. }
  51.  
  52. void initializeMatrix(char **matrix, const int from_vertex, const int to_vertex) {
  53.     addVertexToMatrix(matrix, from_vertex, to_vertex);
  54. }
  55.  
  56. int dfs(char **matrix, const int N, const int vertex, int *res) {
  57.     if (matrix[vertex - 1][0] == WHITE) {
  58.         static int c = 0;
  59.         matrix[vertex - 1][0] = GREY;
  60.         for (int j = N; j >= 1; --j) {
  61.             if (isVertexInMatrix(matrix, vertex, j))
  62.                 if (dfs(matrix, N, j, res) == IMPOSSIBLE_TO_SORT)
  63.                     return IMPOSSIBLE_TO_SORT;
  64.         }
  65.         matrix[vertex - 1][0] = BLACK;
  66.         res[c++] = vertex;
  67.     }
  68.     if (matrix[vertex - 1][0] == GREY)
  69.         return IMPOSSIBLE_TO_SORT;
  70.     return SORTED;
  71. }
  72.  
  73. int topologicalSort(char **matrix, const int N, int *res) {
  74.     for (int i = 0; i < N; ++i) {
  75.         if (matrix[i][0] == WHITE) {
  76.             if (dfs(matrix, N, i + 1, res) == IMPOSSIBLE_TO_SORT) {
  77.                 return IMPOSSIBLE_TO_SORT;
  78.             }
  79.         }
  80.         if (matrix[i][0] == GREY) {
  81.             return IMPOSSIBLE_TO_SORT;
  82.         }
  83.     }
  84.     return SORTED;
  85. }
  86.  
  87. void freeMem(char **arr, const int N) {
  88.     for (int i = 0; i < N; ++i) {
  89.         free(arr[i]);
  90.     }
  91.     free(arr);
  92. }
  93.  
  94. void printResult(const int *res, const int N) {
  95.     for (int i = N - 1; i >= 0; --i) {
  96.         if (res[i])
  97.             printf("%d ", res[i]);
  98.     }
  99. }
  100.  
  101. enum InitializeState initializeVariables(int *N, int *M, char ***array) {
  102.     int lines = 0;
  103.     int read = 0;
  104.     if ((read = fscanf(stdin, "%d", N)) != EOF && read > 0) {
  105.         if (*N > 2000 || *N < 0) {
  106.             return BAD_NUMBER_OF_VERTICES;
  107.         }
  108.         lines++;
  109.     } else {
  110.         return BAD_NUMBER_OF_LINES_BEFORE;
  111.     }
  112.     if ((read = fscanf(stdin, "%d", M)) != EOF && read > 0) {
  113.         if (*M < 0 || *M > (*N * (*N + 1)) / 2) {
  114.             return BAD_NUMBER_OF_EDGES;
  115.         }
  116.         lines++;
  117.     } else {
  118.         return BAD_NUMBER_OF_LINES_BEFORE;
  119.     }
  120.     int from_vertex, to_vertex;
  121.     *array = createMatrix(*N);
  122.     while ((read = fscanf(stdin, "%d %d", &from_vertex, &to_vertex)) != EOF && read > 0) {
  123.         lines++;
  124.         if (checkVertex(from_vertex, *N) == BAD_VERTEX || checkVertex(to_vertex, *N) == BAD_VERTEX) {
  125.             return BAD_VERTEX;
  126.         }
  127.         initializeMatrix(*array, from_vertex, to_vertex);
  128.     }
  129.  
  130.     if (lines < *M + 2) {
  131.         return BAD_NUMBER_OF_LINES_AFTER;
  132.     }
  133.     return OK;
  134. }
  135.  
  136. int main(void) {
  137.     int N;
  138.     int M;
  139.     char **map = NULL;
  140.     int res[2001] = {0};
  141.     switch (initializeVariables(&N, &M, &map)) {
  142.         case BAD_VERTEX:
  143.             freeMem(map, N);
  144.             puts("bad vertex");
  145.             return 0;
  146.         case BAD_NUMBER_OF_LINES_BEFORE:
  147.             puts("bad number of lines");
  148.             return 0;
  149.         case BAD_NUMBER_OF_LINES_AFTER:
  150.             freeMem(map, N);
  151.             puts("bad number of lines");
  152.             return 0;
  153.         case BAD_NUMBER_OF_EDGES:
  154.             puts("bad number of edges");
  155.             return 0;
  156.         case BAD_NUMBER_OF_VERTICES:
  157.             puts("bad number of vertices");
  158.             return 0;
  159.         case OK:
  160.             break;
  161.     }
  162.     if (topologicalSort(map, N, res) == IMPOSSIBLE_TO_SORT) {
  163.         puts("impossible to sort");
  164.         freeMem(map, N);
  165.         return 0;
  166.     }
  167.     freeMem(map, N);
  168.     printResult(res, N);
  169.  
  170.     return EXIT_SUCCESS;
  171. }
  172.  
Advertisement
Add Comment
Please, Sign In to add comment