GastonFontenla

Kruskal

Jun 2nd, 2018
236
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.73 KB | None | 0 0
  1. #include <iostream>
  2. #include <vector>
  3. #include <algorithm> ///sort
  4.  
  5. using namespace std;
  6.  
  7. vector <int> idComponente;
  8. vector <vector <int> > componente;
  9.  
  10. bool unionFind(int nodoA, int nodoB)
  11. {
  12.     int compA = idComponente[nodoA];
  13.     int compB = idComponente[nodoB];
  14.  
  15.     if(compA == compB) ///Están en la misma componente
  16.         return false;
  17.  
  18.     int tamA = componente[compA].size();
  19.     int tamB = componente[compB].size();
  20.  
  21.     ///La idea es siempre mover la componenteA hacia la componenteB
  22.     ///Pero para eso, la componenteA siempre debe ser igual o menor a la componenteB
  23.     if(tamA > tamB) ///Este pequeño checkeo hace que sea eficiente
  24.     {
  25.         swap(compA, compB);
  26.         swap(tamA, tamB);
  27.     }
  28.  
  29.     for(int i=0; i<tamA; i++)
  30.     {
  31.         int nodo = componente[compA][i];
  32.         componente[compB].push_back(nodo); ///Muevo a la otra componente
  33.         idComponente[nodo] = compB; ///Reasigno id de componente
  34.     }
  35.  
  36.     ///Opcional: Se puede limpiar a la componenteA ya que no existe mas, sus elementos se movieron a componenteB
  37.     componente[compA].clear();
  38.  
  39.     return true;
  40. }
  41.  
  42. struct arista
  43. {
  44.     int desde, hacia, costo;
  45. };
  46.  
  47. bool operator<(const arista &a, const arista &b)
  48. {
  49.     ///Esta función devuelde si arista "a" es menor a arista "b"
  50.     return a.costo < b.costo;
  51. }
  52.  
  53. vector <arista> Kruskal(vector <arista> a, int cantNodos)
  54. {
  55.     idComponente.resize(cantNodos+1);
  56.     componente.resize(cantNodos+1);
  57.  
  58.     ///Inicialmente cada nodo pertenece a su propia componente
  59.  
  60.     for(int i=1; i<=cantNodos; i++)
  61.     {
  62.         idComponente[i] = i;
  63.         componente[i] = vector <int> (1, i);
  64.     }
  65.  
  66.     vector <arista> arbolCubridorMinimo;
  67.  
  68.     sort(a.begin(), a.end());
  69.  
  70.     ///Un arbol cubridor mínimo (minimum spanning tree) tiene aritas = cantNodos-1 ya que es un árbol
  71.     int i = 0;
  72.     while(i < a.size() && arbolCubridorMinimo.size() < cantNodos-1)
  73.     {
  74.         if(unionFind(a[i].desde, a[i].hacia))
  75.             arbolCubridorMinimo.push_back(a[i]);
  76.         i++;
  77.     }
  78.  
  79.     return arbolCubridorMinimo;
  80. }
  81.  
  82. int main()
  83. {
  84.     int cantNodos, cantAristas;
  85.     cin >> cantNodos >> cantAristas;
  86.  
  87.     vector <arista> a(cantAristas);
  88.  
  89.     for(int i=0; i<cantAristas; i++)
  90.         cin >> a[i].desde >> a[i].hacia >> a[i].costo;
  91.  
  92.     vector <arista> resultado = Kruskal(a, cantNodos);
  93.  
  94.     int costoTotal = 0;
  95.  
  96.     cout << "El arbol cubridor minimo es: " << endl;
  97.  
  98.     for(int i=0; i<resultado.size(); i++)
  99.     {
  100.         cout << "(" << resultado[i].desde << ",";
  101.         cout << resultado[i].hacia << ") -> " << resultado[i].costo << endl;
  102.         costoTotal += resultado[i].costo;
  103.     }
  104.  
  105.     cout << "El costo total es: " << costoTotal << endl;
  106.  
  107.     return 0;
  108. }
Advertisement
Add Comment
Please, Sign In to add comment