You are on page 1of 16

Algorithms and More

Blog about programming!

RBOL DE EXPANSIN MNIMA: ALGORITMO DE KRUSKAL


Publicado el abril 19, 2012| 15 comentarios

Antes de explicar directamente el algoritmo de Kruskal, comenzar dando conceptos sobre que es un rbol de
expansin mnima para entender mejor el problema.
rbol de Expansin
Dado un grafo conexo, no dirigido G. Un rbol de expansin es un rbol compuesto por todos los vrtices y algunas
(posiblemente todas) de las aristas de G. Al ser creado un rbol no existirn ciclos, adems debe existir una ruta
entre cada par de vrtices.
Un grafo puede tener muchos arboles de expansin, veamos un ejemplo con el siguiente grafo:

En la imagen anterior se puede observar que el grafo dado posee 3 arboles de expansin, dichos arboles cumplen
con las propiedades antes mencionadas como son unir todos los vrtices usando algunas aristas.
rbol de Expansin Mnima
Dado un grafo conexo, no dirigido y con pesos en las aristas, un rbol de expansin mnima es un rbol compuesto
por todos los vrtices y cuya suma de sus aristas es la de menor peso. Al ejemplo anterior le agregamos pesos a sus

aristas y obtenemos los arboles de expansiones siguientes:

De la imagen anterior el rbol de expansin mnima seria el primer rbol de expansin cuyo peso total es 6.
El problema de hallar el rbol de Expansin Mnima (MST) puede ser resuelto con varios algoritmos, los mas
conocidos con Prim y Kruskal ambos usan tcnicas voraces (greedy).
Algoritmo de Kruskal
Para poder comprender el algoritmo de kruskal ser necesario revisar primer el tutorial de Union-Find.
Como trabaja:
Primeramente ordenaremos las aristas del grafo por su peso de menor a mayor. Mediante la tcnica greedy Kruskal
intentara unir cada arista siempre y cuando no se forme un ciclo, ello se realizar mediante Union-Find. Como
hemos ordenado las aristas por peso comenzaremos con la
arista de menor peso, si los vrtices que contienen dicha
arista no estn en la misma componente conexa entonces
los unimos para formar una sola componente mediante
Union(x , y), para revisar si estn o no en la misma
componente conexa usamos la funcin SameComponent(x ,
y) al hacer esto estamos evitando que se creen ciclos y que la
arista que une dos vrtices siempre sea la mnima posible.
Algoritmo en Pseudocdigo

mtodo Kruskal(Grafo):

inicializamos MST como vaco

inicializamos estructura unin-find

ordenamos las aristas del grafo por peso de menor a mayor.

para cada arista e que une los vrtices u y v

si u y v no estn en la misma componente

agregamos la arista e al MST

realizamos la unin de las componentes de u y v

Ejemplo y cdigo paso a paso


Tengamos el siguiente grafo no dirigido:

Como podemos ver en la imagen anterior la definicin de nuestro grafo en cdigo sera:
1
2
3
4
5
6
7

struct Edge{
int origen; //Vrtice origen
int destino; //Vrtice destino
int peso; //Peso entre el vrtice origen y destino
Edge(){}

}arista[ MAX ]; //Arreglo de aristas para el uso en kruskal

Primeramente usaremos el mtodo MakeSet de unin-find para inicializar cada componente, obteniendo las
siguientes componentes conexas iniciales:

Ahora el siguiente paso es ordenar las aristas del grafo en orden ascendente:

Para el ordenamiento podemos usar las libreras predefinidas de Java y C++ como estamos ordenando estructuras
necesitamos un comparador, en este caso estamos ordenando por peso por lo tanto dentro de la estructura antes
definida agregamos:
1
2
3
4
5
6
7

struct Edge{

//Comparador por peso, me servira al momento de ordenar lo realizara en orden ascendent
//Cambiar signo a > para obtener el arbol de expansion maxima
bool operator<( const Edge &e ) const {
return peso < e.peso;
}

}arista[ MAX ]; //Arreglo de aristas para el uso en kruskal

Ordenamos el arreglo de aristas mediante lo siguiente:


1

std::sort( arista , arista + E ); //Ordenamos las aristas por su comparador

Lo siguiente ser recorrer todas las aristas ya ordenadas y verificar si sus vrtices estn o no en la misma
componente.
La primera arista a verificar es la que une a los vrtices 8 y 7, verificamos si estn en la misma componente, para
ello hacemos Find(8) , Find(7):

Como podemos observar en la tabla y en la misma imagen no estn en la misma componente conexa, por tanto esta
arista es valida para el MST as que unimos los vrtices por el mtodo de Union( 8 , 7 ).

Continuamos con la siguiente arista:

Observamos la tabla de Union-Find y vemos que Find(3) != Find(9). Entonces es posible realizar la unin de ambas
componentes:

Continuamos con la siguiente arista:

En la imagen podemos observar que ambos vrtices no estn en la misma componente, por tanto realizamos la
Union( 6 , 7 ):

Continuamos con la siguiente arista, los vrtices 1 y 2 no estn en la misma componente conexa:

Realizamos la Union(1,2):

Continuamos con la siguiente arista:

Al observar la imagen los vrtices 3 y 6 estn en distinta componentes conexas. Entonces realizamos la Union(3,6) y
actualizamos la tabla de Union-Find.

Continuamos con la siguiente arista:

En este caso si observamos la imagen los vrtices 7 y 9 estn en la misma componente conexa; asimismo en la tabla
de Union-Find el elemento raz del vrtice 7 es el mismo que el del vrtice 9 por ello afirmamos que estn el a
misma componente conexa, por lo tanto no habr que realizar la unin de ambos vrtices. Con esto evitamos tener
ciclos en el rbol de expansin mnima.
Continuamos con la siguiente arista:

Al observar la imagen los vrtices 3 y 4 no estn en la misma componente conexa por lo tanto realizamos la
Union(3,4) en el grafo:

Continuamos con la siguiente arista:

Los vrtices 8 y 9 estn en la misma componente conexa por lo tanto no realizamos Unin de vrtices. Continuemos
con la siguiente arista:

Los vrtices 1 y 8 estn diferentes componentes. Realizamos la Union(1,8) en el grafo:

Continuamos con la siguiente arista:

Los vrtices 2 y 3 estn en la misma componente conexa por lo tanto no realizamos Union de componentes.
Continuamos con la siguiente arista:

Los vrtices 4 y 7 no estn en la misma componente conexa, realizamos Union(4,5) en el grafo:

Como podemos observar ya estn todos los vrtices del grafo conectados as que al momento de continuar viendo
las dems aristas ordenadas siempre tendremos e l caso de que ya estn en la misma componente conexa por lo
tanto el rbol de Expansin Mnima para el grafo es el siguiente:

El peso total del rbol de expansin mnima para el grafo mostrado es 39.
En cdigo simplemente es iterar sobre el arreglo de aristas ingresado y ordenado obteniendo sus respectivos datos.
Para verificar si estn o no en la misma componente usamos el mtodo sameComponent explicado en el tutorial de

Union-Find:
1
2
3
4
5
6
7
8
9
10
11

for( int i = 0 ; i < E ; ++i ){ //Recorremos las aristas ya ordenadas por peso
origen = arista[ i ].origen; //Vrtice origen de la arista actual
destino = arista[ i ].destino; //Vrtice destino de la arista actual
peso = arista[ i ].peso; //Peso de la arista actual
//Verificamos si estan o no en la misma componente conexa
if( !sameComponent( origen , destino ) ){ //Evito ciclos
total += peso; //Incremento el peso total del MST
MST[ numAristas++ ] = arista[ i ]; //Agrego al MST la arista actual
Union( origen , destino ); //Union de ambas componentes en una sola
}
}

Verificacin de MST
Para que sea un MST vlido el nmero de aristas debe ser igual al nmero de vrtices 1. Esto se cumple debido a
que el MST debe poseer todos los vrtices del grafo ingresado y adems no deben existir ciclos. Si vemos el ejemplo
antes explicado tenemos en el MST:
Nmero de Aristas = 8
Nmero de Vrtices = 9
Cumple con lo dicho -> 9 1 = 8 por tanto tenemos un MST vlido. Veamos otro ejemplo teniendo como grafo
ingresado lo siguiente:

Como podemos observar el grafo ingresado posee 2 componentes conexas, al aplicar kruskal obtendremos los
siguientes MST:

En la imagen podemos observar el MST luego de aplicar kruskal, sin embargo no es un MST vlido porque no tiene
1 componente conexa que posea todos los vrtices, comprobemos:
Nmero de Aristas = 7
Nmero de Vrtices = 9
No cumple lo dicho inicialmente 9 1 != 7 por lo tanto tenemos un MST invalido. En cdigo basta con un if:
1
2
3
4
5
6
7

//Si el MST encontrado no posee todos los vrtices mostramos mensaje de error
//Para saber si contiene o no todos los vrtices basta con que el numero
//de aristas sea igual al numero de vertices - 1
if( V - 1 != numAristas ){
puts("No existe MST valido para el grafo ingresado, el grafo debe ser conexo.");
return;
}

Problemas de diferentes Jueces


UVA
908 Re-connecting Computer Sites
1208 Oreon
10034 Freckles
10462 Is There A Second Way Left?
10600 ACM contest and Blackout
10842 Traffic Flow
11228 Transportation System
11631 Dark roads

11710 Expensive subway


11733 Airports
11747 Heavy Cycle Edges
11857 Driving Range
COJ
1016 Freckles
1690 Bad Cowtractors
TOPCODER
SRM 356 DIV2-1000 RoadReconstruction
SRM 492 DIV2 1000 TimeTravellingSalesman
HDU
1102 Constructing Roads
POJ
2377 Bad Cowtractors
2421 Constructing Roads
TJU
2531 Oreon
Cdigos:
Implementacin del algoritmo en C++: Algoritmo de Kruskal
Implementacin del algoritmo en JAVA: Algoritmo de Kruskal
Por Jhosimar George Arias Figueroa

SHARE THIS:

Twitter

Facebook

Me gusta
S el primero en decir que te gusta.

Esta entrada fue publicada en Algorithms, Main y etiquetada graph, kruskal, minimum spanning tree, mst, union
find. Guarda el enlace permanente.

15 RESPUESTAS A RBOL DE EXPANSIN MNIMA: ALGORITMO DE KRUSKAL

azael sebastian lucio florido | diciembre 7, 2012 en 2:56 am | Responder


excelente trabajo bro muy bueno el blog, me gustaria que hablaras sobre bellman ford y dp saludos y
gracias por la informacion

Angel Larios | febrero 6, 2013 en 3:11 pm | Responder


como seria en el caso de empezar con el nodo 7 me dara lo mismo

jariasf | febrero 6, 2013 en 5:53 pm | Responder


A que parte te refieres??

Mauri Wilde | junio 11, 2013 en 10:05 pm | Responder


Mucha gracias! En serio me fuiste de mucha ayuda
Sigue con el buen trabajo!

jhomoh | septiembre 28, 2013 en 4:19 pm | Responder


como lo hago dinamicamente

Adrin | marzo 28, 2014 en 10:22 am | Responder


Te rifas solo vi el pseudocdigo y pude hacerlo (Y)

jaime | junio 14, 2014 en 2:38 pm | Responder


No funciona el codigo

jariasf | junio 15, 2014 en 12:57 pm | Responder


Que parte no funciona? Codigo JAVA o C++?

welington | junio 22, 2014 en 5:04 pm | Responder


Muy bueno el codigo, pero como haria para por el input en un file.txt ?

Rolando | diciembre 14, 2014 en 5:56 pm | Responder


COMO ACCEDER AL REVOLUCIONARIO DE UVA mas que todo al problema oreony otros problemas.

Rolando | diciembre 14, 2014 en 5:56 pm | Responder


perdon al solucionario

jariasf | diciembre 15, 2014 en 9:41 am | Responder


No hay solucionario oficial de UVA. Si tienes dudas sobre algo puedes consultar en sus foros:
http://online-judge.uva.es/board/viewtopic.php?f=61&t=76006
Como casos de prueba, errores en codigo, etc.

Pepe | enero 26, 2015 en 8:34 pm | Responder


que buen tutorial, si no te molesta me gustara usarlo para explicar MST a mis alumnos

jariasf | enero 26, 2015 en 8:40 pm | Responder


Gracias, usalo donde desees para eso estamos para ayudar

Santiago Mesa Mosquera | junio 8, 2015 en 4:12 pm | Responder


Muchas gracias, esta excelente este articulo y todo su bloc es espectacular, demasiado til, lo felicito.

Crea un blog o un sitio web gratuitos con WordPress.com.

El tema Coraline.

You might also like