Advertisement
Guest User

Untitled

a guest
Apr 8th, 2020
162
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 8.31 KB | None | 0 0
  1. #define ll long long
  2.  
  3. #define boolean int
  4. #define false 0
  5. #define true 1
  6.  
  7. #define MAX_VERTICES 5000
  8.  
  9. #include <stdio.h>
  10. #include <mm_malloc.h>
  11. #include <limits.h>
  12.  
  13. #define MAX_LENGTH INT_MAX
  14.  
  15. typedef enum {
  16.     SUCCESS,
  17.     OUT_OF_MEMORY,
  18.     BAD_NUMBER_VERTICES,
  19.     BAD_NUMBER_EDGES,
  20.     BAD_VERTEX,
  21.     BAD_LENGTH,
  22.     BAD_INPUT,
  23.     NO_SPAN_TREE
  24. } ExitCodes;
  25.  
  26. const char* exitMessages[] = {
  27.         "success",
  28.         "out of memory",
  29.         "bad number of vertices",
  30.         "bad number of edges",
  31.         "bad vertex",
  32.         "bad length",
  33.         "bad number of lines",
  34.         "no spanning tree"
  35. };
  36.  
  37. typedef struct _list List;
  38.  
  39. struct _list {
  40.     int vertice;
  41.     int length;
  42.     List* next;
  43. };
  44.  
  45. typedef struct _edge Edge;
  46.  
  47. struct _edge {
  48.     int v1;
  49.     int v2;
  50.     ll priority;
  51. };
  52.  
  53. void swap(void* first, void* second, size_t size) {
  54.     for (size_t i = 0; i < size; i++) {
  55.         char temp = *((char*)(first) + i);
  56.         *((char*)(first) + i) = *((char*)(second) + i);
  57.         *((char*)(second) + i) = temp;
  58.     }
  59. }
  60.  
  61. ExitCodes checkInput(int v, int e) {
  62.     if (v < 0 || v > MAX_VERTICES) {
  63.         return BAD_NUMBER_VERTICES;
  64.     }
  65.  
  66.     if (e < 0 || e > v * (v + 1) / 2) {
  67.         return BAD_NUMBER_EDGES;
  68.     }
  69.  
  70.     return SUCCESS;
  71. }
  72.  
  73. ExitCodes fillGraph(List** arrayOfLists, int vertices, int edges) {
  74.     for (int i = 0; i < edges; i++) {
  75.         int v1, v2;
  76.         long long length;
  77.         if (scanf("%d%d%lli", &v1, &v2, &length) < 3) {
  78.             return BAD_INPUT;
  79.         }
  80.  
  81.         if ((v1 < 1 || v1 > vertices) || (v2 < 1 || v2 > vertices)) {
  82.             return BAD_VERTEX;
  83.         }
  84.  
  85.         if (length < 0 || length > MAX_LENGTH) {
  86.             return BAD_LENGTH;
  87.         }
  88.  
  89.         if (!arrayOfLists[v1 - 1]) {
  90.             arrayOfLists[v1 - 1] = (List*)calloc(1, sizeof(List));
  91.             arrayOfLists[v1 - 1] -> vertice = v2 - 1;
  92.             arrayOfLists[v1 - 1] -> length = (int)length;
  93.         } else {
  94.             List* newList = (List*)calloc(1, sizeof(List));
  95.             newList -> vertice = v2 - 1;
  96.             newList -> length = (int)length;
  97.             newList -> next = arrayOfLists[v1 - 1];
  98.             arrayOfLists[v1 - 1] = newList;
  99.         }
  100.  
  101.         if (!arrayOfLists[v2 - 1]) {
  102.             arrayOfLists[v2 - 1] = (List*)calloc(1, sizeof(List));
  103.             arrayOfLists[v2 - 1] -> vertice = v1 - 1;
  104.             arrayOfLists[v2 - 1] -> length = (int)length;
  105.         } else {
  106.             List* newList = (List*)calloc(1, sizeof(List));
  107.             newList -> vertice = v1 - 1;
  108.             newList -> length = (int)length;
  109.             newList -> next = arrayOfLists[v2 - 1];
  110.             arrayOfLists[v2 - 1] = newList;
  111.         }
  112.     }
  113.  
  114.     return SUCCESS;
  115. }
  116.  
  117. boolean checkSpanTree(List** arrayOfLists, int vertices) {
  118.     if (vertices == 0) {
  119.         return false;
  120.     } else if (vertices == 1) {
  121.         return true;
  122.     }
  123.  
  124.     for (int i = 0; i < vertices; i++) {
  125.         if (!arrayOfLists[i]) {
  126.             return false;
  127.         }
  128.     }
  129.  
  130.     return true;
  131. }
  132.  
  133. ExitCodes PrimAlgorithm(List** arrayOfLists, int vertices) {
  134.     Edge* pQueue = (Edge*)calloc((size_t)vertices, sizeof(Edge));
  135.     int* indexes = (int*)calloc((size_t)vertices, sizeof(int));
  136.     int* arrVertices = (int*)calloc((size_t)vertices, sizeof(int));
  137.     boolean* used = (boolean*)calloc((size_t)vertices, sizeof(boolean));
  138.     if (!pQueue || !indexes || !arrVertices || !used) {
  139.         return OUT_OF_MEMORY;
  140.     }
  141.  
  142.     for (int i = 0; i < vertices; i++) {
  143.         pQueue[i].v1 = vertices;
  144.         pQueue[i].v2 = vertices;
  145.         pQueue[i].priority = (i == 0 ? 0 : (ll)MAX_LENGTH + 1);
  146.         indexes[i] = i;
  147.         arrVertices[i] = i;
  148.         used[i] = false;
  149.     }
  150.  
  151.     int size = vertices;
  152.     for (int i = 0; i < vertices; i++) {
  153.         if (i > 0) {
  154.             printf("%d %d\n", pQueue[0].v1 + 1, pQueue[0].v2 + 1);
  155.         }
  156.  
  157.         used[arrVertices[0]] = true;
  158.         swap(&pQueue[0], &pQueue[size - 1], sizeof(Edge));
  159.         swap(&indexes[arrVertices[0]], &indexes[arrVertices[size - 1]], sizeof(int));
  160.         swap(&arrVertices[0], &arrVertices[size - 1], sizeof(int));
  161.         size--;
  162.  
  163.         int index = 0;
  164.         while (2 * index + 1 < size) {
  165.             if (2 * index + 2 >= size) {
  166.                 if (pQueue[index].priority > pQueue[2 * index + 1].priority) {
  167.                     swap(&pQueue[index], &pQueue[2 * index + 1], sizeof(Edge));
  168.                     swap(&indexes[arrVertices[index]], &indexes[arrVertices[2 * index + 1]], sizeof(int));
  169.                     swap(&arrVertices[index], &arrVertices[2 * index + 1], sizeof(int));
  170.  
  171.                     index = 2 * index + 1;
  172.                 } else {
  173.                     break;
  174.                 }
  175.             } else {
  176.                 if (pQueue[2 * index + 1].priority < pQueue[2 * index + 2].priority) {
  177.                     if (pQueue[index].priority > pQueue[2 * index + 1].priority) {
  178.                         swap(&pQueue[index], &pQueue[2 * index + 1], sizeof(Edge));
  179.                         swap(&indexes[arrVertices[index]], &indexes[arrVertices[2 * index + 1]], sizeof(int));
  180.                         swap(&arrVertices[index], &arrVertices[2 * index + 1], sizeof(int));
  181.  
  182.                         index = 2 * index + 1;
  183.                     } else {
  184.                         break;
  185.                     }
  186.                 } else {
  187.                     if (pQueue[index].priority > pQueue[2 * index + 2].priority) {
  188.                         swap(&pQueue[index], &pQueue[2 * index + 2], sizeof(Edge));
  189.                         swap(&indexes[arrVertices[index]], &indexes[arrVertices[2 * index + 2]], sizeof(int));
  190.                         swap(&arrVertices[index], &arrVertices[2 * index + 2], sizeof(int));
  191.  
  192.                         index = 2 * index + 2;
  193.                     } else {
  194.                         break;
  195.                     }
  196.                 }
  197.             }
  198.         }
  199.  
  200.         /*for (int j = 0; j < vertices; j++) {
  201.             printf("%d %d %lli\n", pQueue[j].v1, pQueue[j].v2, pQueue[j].priority);
  202.         }
  203.         printf("\n");*/
  204.  
  205.         for (List* cur = arrayOfLists[arrVertices[size]]; cur; cur = cur -> next) {
  206.             if (used[cur -> vertice]) {
  207.                 continue;
  208.             }
  209.  
  210.             if (pQueue[indexes[cur -> vertice]].priority > cur -> length) {
  211.                 pQueue[indexes[cur -> vertice]].v1 = cur -> vertice;
  212.                 pQueue[indexes[cur -> vertice]].v2 = arrVertices[size];
  213.                 pQueue[indexes[cur -> vertice]].priority = cur -> length;
  214.  
  215.                 int curIndex = indexes[cur -> vertice];
  216.                 while (curIndex > 0) {
  217.                     if (pQueue[curIndex].priority < pQueue[(curIndex - 1) / 2].priority) {
  218.                         swap(&pQueue[curIndex], &pQueue[(curIndex - 1) / 2], sizeof(Edge));
  219.                         swap(&indexes[arrVertices[curIndex]], &indexes[arrVertices[(curIndex - 1) / 2]], sizeof(int));
  220.                         swap(&arrVertices[curIndex], &arrVertices[(curIndex - 1) / 2], sizeof(int));
  221.  
  222.                         curIndex /= 2;
  223.                     } else {
  224.                         break;
  225.                     }
  226.                 }
  227.             }
  228.         }
  229.  
  230.         /*for (int j = 0; j < vertices; j++) {
  231.             printf("%d %d %lli\n", pQueue[j].v1, pQueue[j].v2, pQueue[j].priority);
  232.         }
  233.         printf("\n");*/
  234.     }
  235.  
  236.     return SUCCESS;
  237. }
  238.  
  239. ExitCodes start() {
  240.     int vertices, edges;
  241.     if (scanf("%d%d", &vertices, &edges) < 2) {
  242.         return BAD_INPUT;
  243.     }
  244.  
  245.     ExitCodes currentAction;
  246.     if ((currentAction = checkInput(vertices, edges)) != SUCCESS) {
  247.         return currentAction;
  248.     }
  249.  
  250.     List** arrayOfLists = (List**)calloc((size_t)vertices, sizeof(List*));
  251.     if (!arrayOfLists) {
  252.         return OUT_OF_MEMORY;
  253.     }
  254.  
  255.     if ((currentAction = fillGraph(arrayOfLists, vertices, edges)) != SUCCESS) {
  256.         return currentAction;
  257.     }
  258.  
  259.     if (!checkSpanTree(arrayOfLists, vertices)) {
  260.         return NO_SPAN_TREE;
  261.     }
  262.  
  263.     if ((currentAction = PrimAlgorithm(arrayOfLists, vertices)) != SUCCESS) {
  264.         return currentAction;
  265.     }
  266.  
  267.     return SUCCESS;
  268. }
  269.  
  270. int main() {
  271.     ExitCodes exec;
  272.     if ((exec = start()) != SUCCESS) {
  273.         printf("%s", exitMessages[exec]);
  274.     }
  275.  
  276.     return exec;
  277. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement