Herowaree

prim

Jun 1st, 2020
93
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.91 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <math.h>
  3. #include <limits.h>
  4.  
  5. void showHeapVector(long int* vertexes_pos, long int* costs, long int* parents, long int heap_size){
  6. //printf("vertex pos: ");
  7. //for(long int i = 0; i <= heap_size; i++){
  8. // printf("%ld ", vertexes_pos[i]);
  9. //}
  10. //printf("\n");
  11.  
  12. for(long int i = 0; i <= heap_size; i++){
  13. printf("vertex: %ld - parent: %ld - cost: %ld\n", vertexes_pos[i], parents[vertexes_pos[i]], costs[vertexes_pos[i]]);
  14. }
  15. printf("\n");
  16. }
  17.  
  18. void min_heapify(long int* vertexes_pos, long int* costs, long int index, long int heap_size){
  19. //printf("enter min_heapify");
  20. long int left = 2*index + 1;
  21. long int right = 2*index + 2;
  22. long int lower;
  23.  
  24. if(left <= heap_size && costs[vertexes_pos[left]] < costs[vertexes_pos[index]]){
  25. lower = left;
  26. }else{
  27. lower = index;
  28. }
  29.  
  30. if(right <= heap_size && costs[vertexes_pos[right]] < costs[vertexes_pos[lower]]){
  31. lower = right;
  32. }
  33.  
  34. if(lower != index){
  35. long int tmp = vertexes_pos[lower];
  36. vertexes_pos[lower] = vertexes_pos[index];
  37. vertexes_pos[index] = tmp;
  38.  
  39. min_heapify(vertexes_pos, costs, lower, heap_size);
  40. }
  41.  
  42. //printf("exiting min_heapify!\n");
  43. }
  44.  
  45. /* returns the vertex with the minimun cost without extract it */
  46. long int heap_minimun(long int* vertexes_pos, long int heap_size){
  47. if(heap_size < 0) return -1;
  48.  
  49. long int vertex = vertexes_pos[0];
  50.  
  51. return vertex;
  52. }
  53.  
  54. long int heap_extract_min(long int* vertexes_pos, long int* costs, long int* parents, long int* heap_size){
  55. //printf("entering in heap_extract_min ...");
  56. if(*heap_size < 0) return -1;
  57.  
  58. long int min = vertexes_pos[0];
  59. vertexes_pos[0] = vertexes_pos[*heap_size];
  60.  
  61. *heap_size = *heap_size - 1;
  62.  
  63. min_heapify(vertexes_pos, costs, 0, *heap_size);
  64.  
  65. //printf(" done!\n");
  66. return min;
  67. }
  68.  
  69. void heap_decrease_key(long int* vertexes_pos, long int* costs, long int* parents, long int heap_size, long int position, long int key){
  70. //printf("entering in heap_decrease_key ...");
  71. //printf("position: %ld\n", position);
  72. //printf("before:\n");
  73. //showHeapVector(vertexes_pos, costs, parents, heap_size);
  74. if(key > costs[vertexes_pos[position]]) return;
  75.  
  76. costs[vertexes_pos[position]] = key;
  77.  
  78. long int parent_position = (long int)floor((position - 1) / 2);
  79. //printf("parent pos: %ld\n", parent_position);
  80.  
  81. long int new_position = position;
  82. while((parent_position >= 0) && costs[vertexes_pos[new_position]] < costs[vertexes_pos[parent_position]]){
  83. //printf("change %ld with %ld\n", vertexes_pos[new_position], vertexes_pos[parent_position]);
  84.  
  85. long int tmp = vertexes_pos[new_position];
  86. vertexes_pos[new_position] = vertexes_pos[parent_position];
  87. vertexes_pos[parent_position] = tmp;
  88.  
  89. new_position = parent_position;
  90.  
  91. if(parent_position <= 0) break;
  92.  
  93. parent_position = (long int)floor((parent_position - 1) / 2);
  94. //printf("new parent: %ld \n", parent_position);
  95. }
  96.  
  97. //printf("after:\n");
  98. //showHeapVector(vertexes_pos, costs, parents, heap_size);
  99. //printf(" done!\n");
  100. }
  101.  
  102. void min_heap_insert(long int* vertexes_pos, long int* parents, long int* costs, long int* heap_size, long int vertex, long int cost){
  103. /* all new vertexs are insert in the end with cost -INF */
  104. *heap_size = *heap_size + 1;
  105. vertexes_pos[*heap_size] = vertex;
  106.  
  107. if(cost == 0){
  108. parents[*heap_size] = vertex;
  109. }else{
  110. parents[*heap_size] = -1;
  111. }
  112.  
  113. costs[*heap_size] = LONG_MAX;
  114.  
  115. heap_decrease_key(vertexes_pos, costs, parents, *heap_size, *heap_size, cost);
  116. }
  117.  
  118. void prim(long int n, long int graph[n][n], long int source){
  119. long int vertexes_pos[n], parents[n], costs[n];
  120. long int heap_size = -1;
  121.  
  122. for(long int i = 0; i < n; i++){
  123. if(i == source){
  124. min_heap_insert(vertexes_pos, parents, costs, &heap_size, i, 0);
  125. }else{
  126. min_heap_insert(vertexes_pos, parents, costs, &heap_size, i, LONG_MAX);
  127. }
  128.  
  129. //printf("insert vertex number %ld\n", i+1);
  130. //showHeapVector(vertexes_pos, costs, parents, heap_size);
  131. }
  132.  
  133. //showHeapVector(vertexes_pos, costs, parents, heap_size);
  134.  
  135. for(long int i = 0; i < n - 1; i++){
  136. long int min = heap_extract_min(vertexes_pos, costs, parents, &heap_size);
  137.  
  138. for(long int j = 0; j <= heap_size; j++){
  139. //printf("computing cost from %ld to %ld - cost: %ld\n", min, vertexes_pos[j], graph[min][vertexes_pos[j]]);
  140.  
  141. if(graph[min][vertexes_pos[j]] > 0 && costs[vertexes_pos[j]] > graph[min][vertexes_pos[j]]){
  142. //printf("Updating cost from %ld to %ld - old: %ld --> new: %ld\n", min, vertexes_pos[j], costs[vertexes_pos[j]], graph[min][vertexes_pos[j]]);
  143.  
  144. heap_decrease_key(vertexes_pos, costs, parents, heap_size, j, graph[min][vertexes_pos[j]]);
  145.  
  146. parents[vertexes_pos[j]] = min;
  147. }
  148. }
  149.  
  150. //showHeapVector(vertexes_pos, costs, parents, heap_size);
  151. //printf("\n");
  152. }
  153.  
  154. long int total = 0;
  155. //printf("\n");
  156. //printf("---- costs ----\n");
  157. for(long int i = 0; i < n; i++){
  158. // printf("vertex: %ld - parent: %ld - cost: %ld\n", i, parents[i], costs[i]);
  159. total += costs[i];
  160. }
  161. printf("%ld\n", total);
  162. }
  163.  
  164. int main(void) {
  165. long int n;
  166.  
  167. scanf("%ld", &n);
  168.  
  169. long int graph[n][n];
  170. long int weight;
  171.  
  172. for(long int i = 0; i < n-1; i++){
  173. for(long int j = 0; j < n - 1 - i; j++){
  174. scanf("%ld", &weight);
  175. graph[i][j+i+1] = weight;
  176. graph[i+j+1][i] = weight;
  177. }
  178. graph[i][i] = 0;
  179. }
  180. graph[n-1][n-1] = 0;
  181.  
  182. prim(n, graph, 0);
  183. }
Advertisement
Add Comment
Please, Sign In to add comment