Advertisement
oaktree

kruskal.cpp (rough)

Jun 6th, 2016
552
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.71 KB | None | 0 0
  1. #include <iostream>
  2. #include <vector>
  3. #include <utility>
  4. #include <algorithm>
  5.  
  6. /* Define an edge struct to handle edges more easily.*/
  7. struct edge {
  8.     int first, second, weight;
  9. };
  10.  
  11. /* Needed to typedef to reduce keystrokes or copy/paste */
  12. typedef std::vector< std::vector< std::pair<int,int> > > adj_list;
  13.  
  14. std::vector<edge> kruskal(const adj_list& graph);
  15. int get_pred(int vertex, const std::vector<int>& pred);
  16.  
  17. int main() {
  18.     int n,m; std::cin >> n >> m;
  19.    
  20.     adj_list graph(n);
  21.     int f,s,w;
  22.     while (m-- > 0) {
  23.         std::cin >> f >> s >> w;
  24.         if (f == s) continue; /* avoid loops */
  25.         graph[ f-1 ].push_back( std::make_pair( s-1 , w ) );
  26.     }
  27.  
  28.     std::vector<edge> result = kruskal(graph);
  29.  
  30.     std::cout << "Here is the minimal tree:\n";
  31.     for (auto& _edge : result) {
  32.         std::cout << char(_edge.first+65) << " connects to " << char(_edge.second+65) << std::endl;
  33.     }
  34.  
  35.     return 0;
  36. }
  37.  
  38. std::vector<edge> kruskal(const adj_list& graph) {
  39.     std::vector<edge> edges, minimum_spanning_tree;
  40.  
  41.     /*
  42.         `pred` will represent our Disjointed sets by naming a set head.
  43.         In the beginning, each node is its own head in its own set.
  44.         We merge sets in the while loop.
  45.     */
  46.     std::vector<int> pred(graph.size());
  47.  
  48.     for (int i = 0, n = graph.size(); i < n; i++) {
  49.         for (auto& _edge : graph[i])
  50.             edges.push_back( { i, _edge.first, _edge.second } );
  51.         pred[i] = i;
  52.     }
  53.  
  54.     /*
  55.         Let's reverse-sort our edge vector
  56.         so that we can just pop off the last (smallest)
  57.         element.
  58.     */
  59.     auto comp = [&](edge left, edge right) { return left.weight > right.weight; };
  60.     std::sort(edges.begin(), edges.end(), comp);
  61.  
  62.     while( !edges.empty() ) {
  63.  
  64.         /* get shortest/least-heavy edge */
  65.         edge shortest = edges.back();
  66.         edges.pop_back();
  67.  
  68.  
  69.         int f_head,s_head; /* first_head, second... */
  70.         f_head = get_pred(shortest.first, pred);
  71.         s_head = get_pred(shortest.second, pred);
  72.  
  73.  
  74.         /*
  75.             If the nodes making up a certain edge are
  76.             not already in the same set...
  77.         */
  78.         if (f_head != s_head) {
  79.             /* Add that edge to the Min. Span. Tree*/
  80.             minimum_spanning_tree.push_back(shortest);
  81.  
  82.             /*
  83.                 Merge the sets by setting
  84.                 the head of one set to the head
  85.                 of the other set.
  86.  
  87.                 If the head of one set is A and the other is C,
  88.                 as long as we point C to A, all nodes part of the
  89.                 set once headed by C will find A in linear time.
  90.             */
  91.             if (f_head < s_head)
  92.                 pred[s_head] = f_head;
  93.             else
  94.                 pred[f_head] = s_head;
  95.         }
  96.     }
  97.  
  98.     return minimum_spanning_tree;
  99. }
  100.  
  101. int get_pred(int vertex, const std::vector<int>& pred) {
  102.     /*
  103.         We stop when a node/vertex is its own predecessor.
  104.         This means we have found the head of the set.
  105.     */
  106.     while(pred[vertex] != vertex)
  107.         vertex = pred[vertex];
  108.     return vertex;
  109. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement