Advertisement
Guest User

My Kruskal

a guest
May 26th, 2015
231
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.00 KB | None | 0 0
  1. //Handed by Oria Gruber to Dr. Leonid Kugel.
  2. //Very important please read: When entering the adjacency matrix, since our graph is undirected
  3. //I only scan the upper half to conserve memory. So if you have an adjacency matrix written down and you want to enter it
  4. //Only enter the upper triangular half, diagonal included.
  5. #include <stdio.h>
  6. #include <conio.h>
  7. #include <stdlib.h>
  8. typedef struct edge //this represents an edge in a graph
  9. {
  10. int vertex1,vertex2,weight;
  11. }edge;
  12. typedef struct parent_array_element //parent_array
  13. {
  14. int parent,depth,root;
  15. }parent_array_element;
  16. int **get_adjacency_matrix(int* num_of_vertices,int *num_of_edges); //scan info from user
  17. edge *get_edges_array(int **graph,int num_of_vertices,int num_of_edges); //put edges of graph into an array
  18. void quick_sort(edge *a,int n); //to sort the edges
  19. parent_array_element *get_parent_array(int num_of_vertices); //initialize parent_array
  20. int find(parent_array_element *parent_array,int x); //returns the root of x's tree
  21. void tree_union(parent_array_element *parent_array,int x,int y); //unifies the trees of x and y
  22. void main()
  23. {
  24. parent_array_element *parent_array;
  25. int **graph,num_of_vertices=0,num_of_edges=0,k=0,edge_counter_in_msp=0,i,sum=0;
  26. edge *edges_array;
  27. graph=get_adjacency_matrix(&num_of_vertices,&num_of_edges); //get the graph
  28. edges_array=get_edges_array(graph,num_of_vertices,num_of_edges); //get the edges
  29. parent_array=get_parent_array(num_of_vertices); //get parent array
  30. printf("The MSP is: \n");
  31. while(edge_counter_in_msp<num_of_vertices-1) //exactly num_of_vertices-1 edges in MSP.
  32. {
  33. if(find(parent_array,edges_array[k].vertex1+1)!=find(parent_array,edges_array[k].vertex2+edges_array[k].vertex1+1)) //x and y dont have the same root
  34. { //so they dont create a cycle
  35. printf("(%d,%d) with weight %d\n",edges_array[k].vertex1+1,1+edges_array[k].vertex2+edges_array[k].vertex1,edges_array[k].weight);
  36. sum+=edges_array[k].weight;
  37. tree_union(parent_array,edges_array[k].vertex1+1,edges_array[k].vertex1+1+edges_array[k].vertex2); //make them same tree
  38. k++;
  39. edge_counter_in_msp++;
  40. continue;
  41. }
  42. else
  43. k++;
  44. }
  45. printf("\nSum of weights: %d",sum);
  46. getch();
  47. }
  48. int **get_adjacency_matrix(int* num_of_vertices,int *num_of_edges)
  49. {
  50. int i,j,k,**graph,rows=0;
  51. printf("Enter the number of vertices in your connected undirected graph:");
  52. scanf("%d",num_of_vertices);
  53. printf("\nVery important: I assume there are no parallel edges\n");
  54. rows=*num_of_vertices;
  55. graph=(int**)malloc(rows*sizeof(int*));
  56. for(i=0;i<rows;i++)
  57. graph[i]=(int*)malloc((rows-i)*sizeof(int));
  58. printf("Please Enter the upper triangular cost-adjacency matrix\n");
  59. for(i=0;i<rows;i++)
  60. {
  61. for(k=0;k<i;k++)
  62. printf(" "); //blank spaces for readability.
  63. for(j=0;j<rows-i;j++)
  64. {
  65. scanf("%d",&(graph[i][j]));
  66. if((j!=0)&&(graph[i][j]>0))
  67. (*num_of_edges)++; //edge found. ignore loops.
  68. }
  69. }
  70. for(i=0;i<rows;i++) //remove loops
  71. graph[i][0]=0;
  72. return graph;
  73. }
  74. edge *get_edges_array(int **graph,int num_of_vertices,int num_of_edges)
  75. {
  76. int i,j,k=0;
  77. edge *edges_array;
  78. edges_array=(edge*)malloc(num_of_edges*sizeof(edge));
  79. for(i=0;i<num_of_vertices;i++)
  80. {
  81. for(j=0;j<num_of_vertices-i;j++)
  82. {
  83. if(graph[i][j]!=0) //edge found
  84. {
  85. edges_array[k].weight=graph[i][j];
  86. edges_array[k].vertex1=i;
  87. edges_array[k].vertex2=j;
  88. k++;
  89. }
  90. }
  91. } //edge_array is done. we now need to sort it.
  92. quick_sort(edges_array,num_of_edges);
  93. return edges_array;
  94. }
  95. void quick_sort (edge *a, int n) //taken from wikipedia, fixed it a little bit
  96. { //so it would work with edges rather than ints
  97. int i, j, p;
  98. edge t;
  99. if (n < 2)
  100. return;
  101. p = a[n / 2].weight;
  102. for (i = 0, j = n - 1;; i++, j--) {
  103. while (a[i].weight < p)
  104. i++;
  105. while (p < a[j].weight)
  106. j--;
  107. if (i >= j)
  108. break;
  109. t = a[i];
  110. a[i] = a[j];
  111. a[j] = t;
  112. }
  113. quick_sort(a, i);
  114. quick_sort(a + i, n - i);
  115. }
  116. parent_array_element *get_parent_array(int num_of_vertices)
  117. {
  118. int i;
  119. parent_array_element *parent_array;
  120. parent_array=(parent_array_element*)malloc((num_of_vertices+1)*sizeof(parent_array_element));
  121. for(i=0;i<num_of_vertices+1;i++)
  122. {
  123. parent_array[i].parent=-1;
  124. parent_array[i].depth=0;
  125. parent_array[i].root=i;
  126. }
  127. return parent_array;
  128. }
  129. int find(parent_array_element *parent_array,int x)
  130. {
  131. return parent_array[x].root;
  132. }
  133. void tree_union(parent_array_element *parent_array,int x,int y)
  134. {
  135. if(parent_array[parent_array[x].root].depth > parent_array[parent_array[y].root].depth) //x tree deeper than y tree. add y to x
  136. { //so trees remain at minimal depth
  137. while(parent_array[y].parent!=-1) //change roots of all nodes in y tree to root of x
  138. {
  139. parent_array[y].root=parent_array[x].root;
  140. y=parent_array[y].parent;
  141. }
  142. parent_array[y].parent=parent_array[x].root; //the parent of root of y is root of x
  143. parent_array[y].root=parent_array[x].root;
  144. return;
  145. }
  146. if(parent_array[parent_array[x].root].depth==parent_array[parent_array[y].root].depth) //same depth. add y to x (arbitrary) and change depth of x
  147. {
  148. while(parent_array[y].parent!=-1) //change roots of all nodes in y tree to root of x
  149. {
  150. parent_array[y].root=parent_array[x].root;
  151. y=parent_array[y].parent;
  152. } //y is now root of y tree
  153. parent_array[y].parent=parent_array[x].root; //the parent of root of y is root of x
  154. parent_array[y].root=parent_array[x].root;
  155. parent_array[parent_array[x].root].depth++;
  156. return;
  157. }
  158. if(parent_array[parent_array[x].root].depth < parent_array[parent_array[y].root].depth) //y tree deeper than x tree. add x to y
  159. { //so trees remain at minimal depth
  160. while(parent_array[x].parent!=-1) //change roots of all nodes in y tree to root of x
  161. {
  162. parent_array[x].root=parent_array[y].root;
  163. x=parent_array[x].parent;
  164. }
  165. parent_array[x].parent=parent_array[y].root; //the parent of root of x is root of y
  166. parent_array[x].root=parent_array[y].root;
  167. return;
  168. }
  169. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement