Sei sulla pagina 1di 74

Grafos es el cuarto capítulo del libro Invitación a la Matemática Discreta (se com-

piló por separado en Context). Los otros capítulos del libro son Teoría de conjuntos,
Sistemas numéricos y teoría elemental de números y Conteo. Son apuntes reunidos
durante varios años en los cursos de matemáticas discretas para la carrera de Inge-
niería de Sistemas y Computación y para la Maestría en Ingeniería de Sistemas y
Computación. El capítulo tiene también una sección con problemas para proponer
a los estudiantes.

1
Invitación a la Matemática Discreta.

Julio Hernando Vargas


Universidad Tecnológica de Pereira

2
Grafos

1 Grafos

1.1 Introducción

Se dice que la teoría de grafos nació con la solución de un problema aparentemente


banal. El problema era llamado el paseo por los siete puentes de Königsberg. En esa
ciudad (actualmente llamada Kaliningrado) había siete puentes sobre el río Pregel
dispuestos como se muestra en la figura 1.1. Los habitantes de la ciudad trataban
de hacer un paseo por los puentes cruzando cada uno de ellos exactamente una vez,
regresando al punto de partida. El gran matemático Leonard Euler se enteró del
problema pero inicialmente le dió poca importancia. En 1736, en una carta a Carl
Ehler escribió:
“... este tipo de solución tiene poca relación con las matemáticas, y yo no en-
tiendo porqué espera usted que un matemático la encuentre, y no cualquiera,
pues la solución se basa solamente en la razón, y su descubrimiento no de-
pende de ningún principio matemático.”

Figura 1.1 Esquema de los puentes de Kön-


ingsberg.

Pero en otra carta del mismo año al matemático italiano Giovanni Marinoni dice:
“El problema es tan banal, pero me parece que merece la atención pues ni la
geometría, ni el algebra, ni el arte de contar son suficientes para resolverlo.
En vista de esto, se me ocurrió preguntarme si pertenece a la geometría de
la posición 1, la que Leibniz a trabajado tanto.”
Finalmente, también en 1736, Euler presentó a la academia de St. Petersburgo el
artículo "Solutio problematis ad geometriam situs pertinentis" que fue publicado
en 1741. En ese artículo no solo solucionaba el problema de los siete puentes de
Königsberg, también generalizaba su solución a cualquier configuración.

1 El término usado por Leibniz era geometriam situs.

3
Grafos

El argumento de Euler, planteado en términos actuales, consistió en considerar los


puentes como los arcos de un grafo siendo los vértices las dos islas y las orillas del
río 2. Es claro que para realizar el recorrido pretendido, por cada puente que se cruze
para llegar a alguna de las regiones, debe haber otro puente diferente que permita
salir de allí. Por lo tanto a cada vértice debe llegar un número par de arcos. Como
en el grafo correspondiente eso no sucede, el problema no tiene solución.

Inicialmente el desarrollo de la teoría de grafos estuvo impulsado esencialmente por


la búsqueda de solución a algunos problemas famosos, considerados por muchos
intrascendentes, como la conjetura de los cuatro colores. En 1852 Francis Guthrie,
un estudiante de matemáticas en el University College London, se preguntó cuantos
colores se necesitaban para colorear un mapa de modo que dos países fronterizos
tuvieran diferentes colores. Conjeturó que cuatro colores eran suficientes, pero no
pudo probarlo. El famoso lógico De Morgan, profesor en la institución, se enteró
del problema pero tampoco pudo probarlo. Este resultó ser uno de los problemas
más famosos y difíciles en teoría de grafos. Y partir de la segunda mitad del siglo
pasado el crecimiento de la teoría ha sido enorme debido principalmente a la gran
cantidad de aplicaciones, principalmente en las ciencias de la computación y a su
relación continuamente creciente con otras áreas de las matemáticas.
El siguiente ejemplo sencillo sirve para mostrar como un problema concreto se puede
modelar usando la teoría de grafos. Dos avenidas se cruzan en una intersección en
la que los cruces permitidos se muestran en la figura 2. El problema consiste en
encontrar un "patrón de tráfico" (una organización de los semáforos) que permita a
cada vehículo cruzar la intersección sin interferir con ningún flujo de tráfico.

Figura 1.2 El problema de la intersección vial.

2 El tratamiento de Euler al problema fue abstracto, nunca dibujó un gráfico en su artículo.

4
Grafos

¿Cómo se puede modelar este problema? Imitando a Euler, omitiendo toda infor-
mación irrelevante para el problema como el ancho de las avenidas o los tiempos de
los semáforos, es claro que lo único que importa para este problema son los flujos
vehiculares que se intersectan y entonces podemos relacionar este problema con un
grafo en el que los vértices corresponden a los diferentes cruces permitidos y en el
que un arco entre dos vértices indica que los cruces correspondientes se intersectan.
Los giros en las esquinas no se consideran pues no interfieren con ningún otro cruce.
Lo que importa es que dos cruces que se intersecten no tengan semáforo en verde
simultáneamente. Se pueden entonces etiquetar los vértices de algún modo para
indicar que se puede hacer el cruce, pero hay que hacerlo de modo que dos vértices
unidos por un arco no tengan la misma etiqueta y tratando de usar el número mínimo
de etiquetas. Visto así, el problema se vuelve un caso particular de un importante
problema llamado el problema del coloreado de un grafo que básicamente consiste en
asignar a cada vértice del grafo un color, buscando usar la menor cantidad posible
de colores con la condición de que dos vértices que estén conectados por un arco no
tengan el mismo color.
Pero, mas interesante aun, resulta que muchos otros problemas aparentemente difer-
entes, como el mencionado problema de los cuatro colores o el problema de la pro-
gramación de exámenes en una facultad para mencionar solo dos, también se pueden
modelar como problemas de coloreado de grafos.

5
Grafos

1.2 Definiciones básicas.

Informalmente un grafo es una idea abstracta que representa conexiones entre obje-
tos. Formalmente un grafo G es una pareja (V, A), donde V es un conjunto cuyos el-
ementos son llamados vértices y A es un subconjunto del conjunto {{u, v}| u, v ∈ V }
cuyos elementos son llamados arcos o aristas. Para referirse a un arco {u, v} se usan
etiquetas como a = {u, v} o simplemente se escribe uv. Los vértices de un grafo
se suelen etiquetar numerandolos como {v1 , . . . , vn } o simplemente con los números
naturales 1, . . . , n.
En los grafos dirigidos, también llamados digrafos, el conjunto de arcos A es un
subconjunto de (V × V ) − ∆, i.e., cada arco es un par ordenado con componentes
distintas. Los grafos se representan (por lo menos en los casos simples) mediante
dibujos en el plano en los que los vértices son puntos o pequeños nodos y los arcos
son líneas o curvas que unen los vértices correspondientes.

Figura 1.3 Un grafo y un digrafo.


Cuando es necesario especificar a qué grafo corresponden los vértices o los arcos se
usa la notación VG o AG .
Nótese que según la anterior definición, un grafo no puede tener arcos paralelos y
tampoco puede tener arcos que inicien y terminen en el mismo vértice. Algunos
autores llaman a estos grafos simples. Supondremos que, a menos que se especifique
lo contrario, los grafos o digrafos serán simples.
Es importante tener presente que no hay una notación unificada en teoría de grafos.
Por ejemplo, algunos autores definen un grafo como una 3−pla, G = (V, A, φ)
donde V y A son conjuntos cualquiera y φ es una función:
φ : A → P2 (V )
llamada función de incidencia. P2 (V ) denota todos los subconjuntos de V de cardi-
nalidad 2. Según esta definición, para el grafo de la figura 1.4

6
Grafos

Figura 1.4 Otra definición de grafo.

la función φ es:
 
1 2 3 4 5 6 7 8
φ= E
 E A A C B B D
A C C D B D F F

Se dice entonces que, por ejemplo, el arco 1 es incidente con los vértices E y A, y
también que los vértices E y A son incidentes con el arco 1. Si uv es un arco en un
grafo no dirigido, también se dice que u y v son los extremos del arco.

Si v es un vértice de un grafo, se define el grado de v, d(v), como

d(v) = |{{x, y} ∈ A|x = v o y = v}|

y se define N (v), el conjunto formado por los vecinos de v, como

N (v) = {x| xv ∈ A ∨ vx ∈ A}

Así, d(v) = |N (v)|


Para el caso de un digrafo, si v es un vértice del grafo, los números
d+ (v) = |{(v, x) ∈ A para algún x ∈ V }|
d− (v) = |{(x, v) ∈ A para algún x ∈ V }|
d(v) = d+ (v) + d− (v)
son llamados grado externo, grado interno y grado, respectivamente.
Un grafo es llamado k-regular si para todos sus vértices v, d(v) = k. Un grafo es
llamado completo si para todos sus vértices v, d(v) = n − 1, donde n = |V |.

7
Grafos

Figura 1.5 Un grafo


3−regular y un grafo completo.

Los grados mínimos y máximos de un grafo se representan con δ(G) y ∆(G), respec-
tivamente.

Dados dos vértices u, v en un grafo G, una paseo 3 entre u y v es una sucesión de


vértices v0 , v1 , . . . , vl tales que:

• u = v0 y v = vl .

• vi vi+1 ∈ A i = 0, . . . , l − 1

Una trayectoria, uT v, entre u y v es un paseo en el que todos los vértices son


diferentes. Un ciclo es un paseo en el que todos los vértices son diferentes, excepto
el primero y el último que son iguales.
Una representación más explícita de una trayectoria es:
a1 a2 an
uT v : u = v0 v1 ······ vl = v

La longitud de una trayectoria se define como el número de arcos que la conforman.


La distancia entre dos vértices u y v, dist(u, v), se define como la longitud de la
trayectoria mas corta que los une. Si no hay trayectoria entre los vértices la distancia
se define como ∞.
Si para dos trayectorias uT1 v y uT2 v , (uT1 v) ∩ (uT2 v) = {u, v}, i.e., si los únicos
vértices que tienen en común son el vértice inicial y el vértice final, se dice que las
trayectorias son internamente disyuntas. Si las dos dos trayectorias uT1 v y uT2 v no
tienen ningún arco en común (pueden tener vértices en común) se llaman trayectorias
disyuntas por arcos
La longitud mínima de un ciclo en un grafo es llamada la cintura del grafo. Si el
grafo no tiene ciclos su cintura es 0. Y La longitud máxima de un ciclo es llamada
su circunferencia. Si el grafo no tiene ciclos su circunferencia es ∞.
El grafo complemento Ḡ de un grafo G=(V, A ) es el grafo G = (V, Ā).

3 walk en inglés.

8
Grafos

Figura 1.6 Un grafo y su complemento.

Figura 1.7 Un grafo, un subgrafo y un subgrafo ‘span’.

Un (di)grafo G0 = (V 0 , A0 ) es subgrafo de un (di)grafo G = (V, A) si y solo si


V 0 ⊆ V y A0 ⊆ A. Se dice que G’ es un subgrafo que cubre 4 a G si V 0 = V .
El grafo G − G0 es el grafo que resulta al eliminar de V los vértices que están en V 0 y
al eliminar de A los arcos que están en A0 . Si U ⊂ V y W ⊂ A, G − U y G − W son
los grafos que resultan al eliminar los vértices en U del grafo y al eliminar los arcos
en W del grafo, respectivamente. Si los subconjuntos constan de un solo elemento
se escribe simplemente G − v o G − a.

4 La traducción del término spanning subgraph no es estandar.

9
Grafos

1.3 Representación de grafos

Según la definición, un grafo está completamente determinado por los conjuntos de


sus vértices y sus arcos. Por ejemplo, para el digrafo de la figura 1.8 esos conjuntos
son
V = {1, 2, 3, 4, 5, 6, 7}
A = {12, 13, 14, 25, 32, 34, 35, 36, 46, 57, 67}
pero esta no es una representación adecuada, menos aun los gráficos, para que un
computador opere con grafos. Una forma más manejable de representar (di)grafos
es usando matrices de adyacencia. Si los vértices están enumerados 1, 2, . . . , n, la
matriz de adyacencia es una matriz n × n, A = (aij ) donde aij = 1 si hay un arco
del i−esimo vértice al j−esimo vértice; 0 en caso contrario. Por ejemplo, el digrafo
de la figura 1.8

Figura 1.8 Un grafo dirigido.

se puede representar con la matriz de adyacencia


 
0 1 1 1 0 0 0
0 0 0 0 1 0 0
 
0 1 0 1 1 1 0
 
A= 0 0 0 0 0 1 0
0 0 0 0 0 0 1
 
0 0 0 0 0 0 1
0 0 0 0 0 0 0
Para un grafo la matriz de adyacencia es simétrica.

10
Grafos

Una de las desventajas de esta forma de representación es que, si el grafo tiene n


vértices, el espacio requerido es Θ(n2 ). Usualmente estas matrices de representación
son matrices dispersas.
La matriz de adyacencia A de un grafo tiene la siguiente propiedad:

Proposición 1 Si (Ak )i,j = m, entonces hay m paseos distintos para ir del vértice
i al vértice j en exactamente k pasos.

Demostración por inducción en k

i. k = 1. Si Ai,j = 1, entonces hay un paseo del arco i al arco j de longitud 1.

ii. Supongamos que la propiedad es cierta para la matriz Ak = (mij ). La compo-


nente ij de la matriz Ak+1 es
ai1 m1j + · · · + ail mlj + · · · + ain mnj

Para l = 1, . . . , n:

− Si ail = 1, hay un arco que conecta el vértice i con el vértice l. Por hipótesis
de inducción mlj nos dice que hay mlj paseos distintos de longitud k del
vértice l al vértice j. Entonces también hay mlj paseos distintos del arco i al
arco j (que empiezan con el arco il) de longitud k + 1.

− Si ail = 0 no es posible pasar del vértice i al vértice l para después buscar un


paseo hasta el vértice j. Por lo tanto no hay paseos que inicien con el arco il
y que sigan hasta el vértice j de longitud k + 1.

Así, la anterior suma nos da el total de paseos distintos del vértice i al vértice j
de longitud k + 1.

Corolario 1 La distancia entre cualquier par de vértices en un grafo cumple:

dist(vi , vj ) = min{k > 0 | (Ak )ij 6= 0}

Haciendo operaciones con la matriz de adyacencia se pueden construir algoritmos


que resuelvan de forma eficiente algunos problemas con grafos. Supongamos, por
ejemplo, que necesitamos saber si un grafo tiene un triángulo (K3 ) como subgrafo.
Para determinar eso es suficiente con comprobar si tanto la matriz de adyacencia A,
como A2 tienen una entrada ij diferente de cero. Esto es así pues si aij 6= 0 hay un
arco entre vi y vj . Y la entrada ij de A2 es ai1 a1j + · · · + ain anj . Si este valor no
es cero es porque existe k 6= i, j (pues aii = ajj = 0) tal que aik y akj no son cero.
Los vértices vi , vj , vk forman un triángulo en el grafo.

11
Grafos

Un grafo también se puede representar usando matrices de incidencia. En una


matriz de incidencia las filas corresponden a los vértices del grafo y las columnas a
los arcos. En la matriz M = (mva ) el valor de mva es 1 si el arco a incide en el
vértice v. Pero solo si el número de arcos es menor al número de vértices, el tamaño
de esta matriz es menor que el tamaño de la matriz de adyacencia. La matriz de
incidencia para el grafo de la figura 1.9 es:

a b c d e f g h
1 1 0 1 1 0 0 0 0
2 0 0 0 0 1 1 1 0
3 0 1 1 0 1 0 0 0
4 0 0 0 1 0 1 0 1
5 1 1 0 0 0 0 0 0
6 0 0 0 0 0 0 1 1

Figura 1.9 Para la


matriz de incidencia.

Otra forma muy usada para representar grafos es usando listas de adyacencia. Aquí
un grafo se puede representar como un diccionario en el que las claves son los nom-
bres de los vértices y los valores son conjuntos o listas A formados por los vértices
conectados con la clave.
ui → Ai = [vi1 , . . . , vik ]

Para los digrafos la orientación de los arcos es ui vik . Por ejemplo, la representación
con listas de adyacencia del grafo de la figura 1.10 es (Scala):

12
Grafos

Figura 1.10

val g1 = Map( ’A’ -> List(’B’,’C’), ’B’ -> List(’A’,’C’, ’D’),


’C’ -> List(’A’,’B’, ’E’), ’D’ -> List(’B’,’E’),
’E’ -> List(’C’,’D’))

La representación de un grafo con listas de adyacencia requiere O(|V | + |A|) espacio.

Para cada caso en particular, una representación puede ser mas conveniente que otra.
Por ejemplo, si se quiere determinar si en un grafo existe un arco uv, la representación
matricial requiere tiempo constante mientras que la representación con listas de
adyacencia requiere un tiempo O(|V |). Y no solamente influye la representación del
grafo, también puede influir la relación entre el número de vértices y el número de
arcos. Las siguientes son dos definiciones relacionadas con esto último:

• Un grafo es denso si el número de arcos es aproximadamente proporcional al


cuadrado del número de vértices, |A| ≈ |V |2 . Informalmente esto quiere decir
que una porción grande de los pares de vértices son adyacentes.

• Un grafo es disperso si el número de arcos es aproximadamente proporcional al


número de vértices, |A| ≈ |V |.

Los siguientes problemas ilustran el anterior comentario:

Digrafos Acíclicos
Cuando se trabaja con digrafos (como por ejemplo en las redes Bayesianas) un prob-
lema muy común consiste en determinar si el digrafo no tiene ciclos. Un algoritmo
que resuelve este problema se basa en algunas propiedades de los digrafos como la
siguiente:

Lema 1 Si G es un digrafo acíclico, G tiene por lo menos un vértice v tal


que d− (v) = 0

13
Grafos

Demostración. Se escoge un vértice v0 . Si d− (v0 ) = 0 ya está. Si no, existe un arco


v1 v0 . Si d− (v1 ) = 0 ya está. Si no, existe un arco v2 v1 con v2 6= v0 pues el digrafo
es acíclico. Si se continua este procedimiento se llega a una sucesión de vértices
distintos v0 , v1 , . . . , vk que debe terminar pues el digrafo es finito. Y d− (vk ) tiene
que ser igual a 0.

El algoritmo supone los vértices numerados de 1 a n y el grafo representado con listas


de adyacencia. Un primer paso consiste en determinar d− (v) para cada vértice. Ai
es la lista de adyacencia para el vértice i.

Para i=1 hasta n haga d− (i) = 0


Para i=1 hasta n haga
Para j ∈ Ai haga d− (j) = d− (j) + 1

Después se crea una lista L con aquellos vértices v para los que d− (v) = 0

Para i=1 hasta n haga si d− (i) = 0 agrege i a la lista L

En caso de que no existan vértices con d− (i) = 0, según el lema 1, el algoritmo debe
retornar que el digrafo no es acíclico.
El algoritmo también puede retornar un ordenamiento topológico de los vértices. Un
ordenamiento topológico es una enumeración ϕ de los vértices tal que para cada
arco ij se cumpla que ϕ(i) < ϕ(j). También puede verse como un cambio en las
etiquetas de los vértices de modo que para cada arco ij se cumpla que i < j.

k=1
Mientras L 6= ∅ haga
Elimine el primer vértice v de L
ϕ(v) ← k; k ← k + 1
Para cada w ∈ Av haga
d− (w) ← d− (w) − 1
Si d− (w) = 0 agrege w a L

Si el valor final de k es n + 1 el algoritmo retorna que el digrafo es acíclico, en caso


contrario no lo es.
La complejidad del anterior algoritmo es Θ(|A|). Puede mostrarse que la compleji-
dad de cualquier algoritmo que determine si un digrafo es acíclico o no usando como
representación la matriz de adyacencia tiene complejidad por lo menos de Ω(|V |2 ).

14
Grafos

El problema de la cerradura transitiva

Un digrafo se llama transitivo si


∀u, v, w ((u, v) ∈ A y (v, w) ∈ A ⇒ (u, w) ∈ A)

Si un digrafo no es transitivo, el problema de la cerradura transitiva consiste en


agregar todos los arcos que hagan falta para obtener un grafo transitivo.

Una estrategia para resolver este problema consiste en recorrer todo el grafo ha-
ciendo corto-circuito en cada vértice. El corto circuito consiste en agregar arcos que
conecten todos los predecesores del vértice con todos los sucesores del vértice. El
siguiente es un seudocódigo para este algoritmo; pred(v, G) es el conjunto formado
por los vértices predecesores de v en el digrafo G y suc(v, G) el conjunto formado
por los vértices sucesores:

Para cada v en G
Para cada x en pred(v, G)
Para cada y en suc(v, G)
agregar (x, y) a los arcos

Supongamos que el grafo está representado como una lista de adyacencia de la forma:
G = [(v1 , sv1 ), (v2 , sv2 ), . . . , (vn , svn )]

Usando programación funcional no es difícil implementar el cortocircuito para cada


vértice:

cortoc(x, sx, g)=


map(g, (y, sy) -> (y, if (esta (x, sy)) union (sx, sy)
else sy end))

Y con esta función se construye la función principal:

cerraduraTrans(G)=
vs= map(G, (x,_) -> x )
foldl(vs
(inG,x) -> cortoc(x, (suc x inG))
inG)

15
Grafos

1.4 Recorriendo grafos

En muchos algoritmos relacionados con grafos es necesario hacer un recorrido por


todos los vértices del grafo en un orden sistemático. Una primera forma de recorrer
un grafo es la búsqueda llamada BFS 5 o búsqueda primero en amplitud. El siguiente
seudocódigo presenta un algoritmo para realizar este tipo de búsqueda.

BFS(grafo G, vértice inicial s)


[Todos los vértices inicialmente no visitados]

1. Marcar s como visitado.

2. Sea Q una cola inicializada con s.

3. Mientras Q 6= ∅
Sacar el primer elemento de Q, llamemoslo v.
Para cada arco vw
Si w no ha sido visitado
i. Marcarlo como visitado
ii. Meter w a la cola

Si en un grafo G tenemos un nodo distinguido s, también en varios algoritmos es


necesario calcular las distancias dist(s, v) desde s a cada vértice v del grafo. Una
pequeña modificación al algoritmo BFS permite calcular dist(s, v) para cada vértice.
Simplemente se le puede agregar al seudocódigo anterior lo siguiente:
Al inicio:
Para cada vértice inicializar dist(s, v) así:

0 si v = s
dist(s, v) =
∞ si v 6= s

Y después de 3i:
Si w no ha sido explorado, haga dist(w) = dist(v) + 1

Usando una representación con listas de adyacencia, en el anterior algoritmo cada


arco es examinado máximo dos veces y por lo tanto la complejidad del algoritmo es
O(|V | + |A|).

5 Por las iniciales en inglés de Breadth First Search

16
Grafos

Otra clase de recorrido de grafos muy usada es el recorrido DFS 6 o primero en


profundidad. Este recorrido se basa en la siguiente función recursiva:

Explorar(vértice v)
Marcar v como visitado
Para cada arco vw en E haga
si w no visitado
Explorar(w)

Y la función principal es:

DFS(grafo G)
Todos los vértices se marcan inicialmente como no visitados.
Para v=1 hasta n haga
Si v no visitado
Explorar(w)

DFS también requiere de un tiempo O(|V | + |A|).


El anterior algoritmo simplemente ‘’visita” todos los vértices del grafo. Pero la
mayoría de algoritmos debe hacer algo más que simplemente visitar. Por ejemplo,
puede ser necesario no solamente visitar todos los vértices del grafo sino también
llevar algún tipo de registro que nos indique el orden en que el recorrido pasó por
los vértices. Una pequeña modificación al anterior algoritmo permite hacer eso. A
cada vértice v se le pueden asociar dos valores, pre(v) y pos(v), que indiquen en
qué ‘’momento” el algoritmo pasó por ellos. Las funciones previsita y posvisita se
encargan de asignar esos valores.

Explorar(vértice v)
Marcar v como visitado
previsitar(v)
Para cada arco vw en E haga
si w no visitado
Explorar(w)
posvisitar(v)

6 Por las iniciales de Deep First Search.

17
Grafos

Los ‘’momentos” del algoritmo los define una variable global ck

Inicializar ck en 1.
previsitar(v)
pre(v) ←ck
ck ←ck + 1
posvisitar(v)
pos(v) ←ck
ck ←ck + 1

1.5 Isomorfismo

Dos grafos G y H son isomorfos si existe una biyección α : VG → VH tal que:


{u, v} ∈ AG si y solo si {α(u), α(v)} ∈ AH

para todos u, v ∈ G. El isomorfismo es una relación de equivalencia simbolizada


como G ' H.
Los grafos de la figura 1.11 son isomorfos

Figura 1.11 Grafos isomorfos.

pues se puede comprobar que la biyección


α : d → 6, a → 5, e → 4, b → 3, f → 2, c → 1

cumple las condiciones de la definición.

18
Grafos

Una propiedad de un grafo se dice preservada por isomorfismos si siempre que G


tenga esa propiedad, todo grafo isomorfo a G también la tiene. Por ejemplo, el grado
de un vértice es una propiedad que los isomorfismos preservan.
Si un conjunto tiene n elementos, hay n2 subconjuntos de cardinalidad 2. Entonces

n
si se tienen n vértices se pueden definir 2( 2 ) grafos. Pero, ¿cuantos hay que no sean
isomorfos a ningún otro? La siguiente tabla muestra que para valores muy pequeños
de n las cifras ya son enormes; g es el número de grafos que se pueden definir y gni
es el número de grafos no isomorfos:

n 1 2 3 4 5 6 7 8 9
g 1 2 8 64 1024 32768 2 097 152 268 435 456 236
gni 1 2 4 11 34 156 1044 12 346 274 668
Tabla 1.1 Número de grafos y de grafos no isomorfos.

La pregunta inmediata es por un algoritmo que determine si dos grafos dados son
isomorfos o no. Nuevamente se podría pensar en usar alguna propiedad matemática
de sus representaciones. Dos matrices A1 y A2 de tamaño n × n son equivalentes
por permutaciones si una se obtiene a partir de la otra haciendo un reordenamiento
de sus filas y el correspondiente reordenamiento de columnas ,i.e., si hay una matriz
de permutación P tal que A1 = P A2 P −1 .
Puede demostrarse que dos (di)grafos, G1 y G2 , son isomorfos si y solo si sus matrices
de adyacencia, A1 y A2 , son equivalentes por permutaciones. Y las matrices son
equivalentes si pertenecen a la misma clase de equivalencia. Este resultado puede
ser la base para un algoritmo ‘ingenuo’ que determine si dos grafos son isomorfos
como el siguiente (ver D. Joyner)

Para i=1, 2
pi ←clase de equivalencia por permutaciones de Ai
A0i ←elemento lexicográficamente maximal de pi
Si A01 = A02 entonces los grafos son isomorfos.

El algoritmo es correcto pero analizandolo en detalle se ve su enorme complejidad.


El problema del isomorfismo de grafos tiene un lugar especial en teoría de la com-
plejidad. No se ha podido probar que sea NP-completo y tampoco se ha construido
un algoritmo polinomial para resolverlo 7

7 En noviembre de 2015, Lászlo Babai, matemático y científico de la computación en la Universidad


de Chicago presentó un algoritmo que podría resolver el problema en tiempo “cuasi-polinomial”.

19
Grafos

La complejidad computacional de problemas como el isomorfismo de grafos tiene


aplicaciones interesantes. Una de ellas es en las llamadas pruebas de conocimiento
cero 8. En una prueba de conocimiento cero básicamente lo que sucede es que alguien
(el probador) quiere demostrarle a otra persona (el juez) que tiene conocimiento de
algo, pero su demostración no debe darle al juez ninguna información acerca de ese
conocimiento 9. El siguiente es un ejemplo concreto usando isomorfismo de grafos.

Supongamos que un probador quiere probarle a un juez que sabe que dos grafos
G0 , G1 son isomorfos. El probador conoce el isomorfismo π entre los grafos pero no
quiere que nadie mas lo conozca. El siguiente ejemplo sencillo ilustra el proceso:
 
1 2 3 4 5
π=
a c e b d

Figura 1.12 Grafos isomorfos para el ejemplo de ZKP.

El probador selecciona entonces aleatoriamente un número e ∈ {0, 1}. Supongamos


que e = 1. Entonces el probador crea una permutación ρ para Ge :
 
a c e b d
ρ=
b a d e c

y envía al juez H = ρ(Ge ).


El juez a su vez también selecciona aleatoriamente un número e0 ∈ {0, 1}, supong-
amos que e0 = 0, y le pide al probador que muestre que Ge0 es isomorfo a H. El
probador entonces calcula:

ρ si e0 = e
σ = (ρ ◦ π)−1 si e0 = 1 y e = 0
ρ◦π si e0 = 0 y e = 1

El siguiente esquema ilustra lo anterior:

8 Zero Knowledge Proofs.


9 Se puede ver en Wikipedia el ejemplo de ‘la puerta mágica en la cueva’

20
Grafos

π ρ
G0 G1 ρ(G1 ) = H
−→ −→
El isomorfismo que el probador le entrega al juez es entonces:
 
a b c d e
2 1 5 3 4

que efectivamente es un isomorfismo entre H y G0


Si por azar e = e0 , es posible que el probador dé una respuesta correcta aun sin
conocer π. Pero si el procedimiento se repite varias veces, la probabilidad de que el
probador siempre dé una respuesta correcta simplemente por azar decrece exponen-
cialmente.

1.6 Grafos conexos

Un grafo G = (V, A) es conexo si para toda partición del conjunto V en dos sub-
conjuntos no vacíos X, Y , hay por lo menos una arista con un extremo en X y el
otro extremo en Y . O lo que es equivalente, si para cada par de vértices u, v en el
grafo, hay por lo menos una trayectoria de u a v.
En un grafo G se define la siguiente relación en el conjunto V:
Si u, v ∈ V, uRv si y solo si hay una trayectoria de u a v.
Esta relación es una relación de equivalencia y sus clases de equivalencia se llaman
las componentes conexas del grafo.
Una pequeña modificación al algoritmo DFS permite encontrar cuantas componentes
conexas tiene un grafo enumerandolas, con la variable cc, y ubicando a cada vértice
en una de esas componentes conexas, su número de componente conexa, ncc. La
idea principal es que la función Explorar encuentra la componente conexa de v.
Entonces simplemente se trata de usar un contador que cambie cada vez que termine
la exploración de un vértice.

Explorar(vértice v)
Marcar v como visitado
ncc ← cc
Para cada arco vw en E haga
si w no visitado
Explorar(w)

21
Grafos

DFS(grafo G)
cc ← 1
Todos los vértices se marcan inicialmente como no visitados.
Para v=1 hasta n haga
Si v no visitado
Explorar(w)
cc ← cc + 1

La complejidad temporal sigue siendo O(|V | + |A|).

1.7 Algunas propiedades

Propongamos la tarea de dibujar un grafo que tenga un número impar de vértices


con grado impar. ¿ No se encuentra? ¿Acaso es imposible?

Proposición 2 En todo grafo, la suma de los grados de los vértices debe ser par
pues:
X
d(v) = 2|A|
v∈V

este resultado a veces es llamado el lema de los saludos: si se totaliza el número de


personas que cada persona saludó en una reunión, el total debe ser igual al doble
del número de saludos.
Usando matrices de incidencia se puede dar una demostración del lema de los saludos
que usa una técnica muy usada en análisis combinatorio llamada técnica de doble
conteo. La suma total de los valores en una matriz se puede calcular de dos formas:
sumando cada columna y luego sumando todos esos resultados, o sumando cada
fila y luego sumando todos los resultados obtenidos. En el caso de una matriz de
incidencia la suma de cada columna debe ser 2 y por lo tanto la suma total es
dos veces el número de arcos. Y la suma de cada fila debe ser el grado del vértice
correspondiente y por lo tanto la suma total debe ser igual a la suma de los grados
de todos los vértices.
De la anterior proposición se deduce el siguiente resultado:

Corolario 2 En todo grafo G hay un número par de vértices con grado impar.
Si se particiona el conjunto V en dos subconjuntos, Vp con los vértices de grado par
y Vi con los vértices de grado impar se tiene que:
X X X
d(v) = d(v) + d(v) = 2|A|
v∈V v∈Vp v∈Vi

22
Grafos

y si a un número par se le suma otro número y el resultado es par, ese otro número
debe ser par.
n−1
Proposición 3 Sea G un grafo con n vértices. Si δ ≥ 2 , entonces G es conexo.

Demostración por reducción al absurdo.


Supongamos que δ ≥ n−1 2 , pero que G no es conexo. Entonces G tiene por lo menos
dos componentes conexas G1 , G2 . Sea v un vértice en G1 . Como d(v) ≥ δ ≥ n−12 ,
n−1
v tiene por lo menos 2 vértices adyacentes que deben estar en G1 , y por lo tanto
G1 tiene por lo menos n−1 n+1
2 + 1 = 2 vértices.
Un argumento similar muestra que lo mismo sucede en G2 .
Pero entonces el grafo G debe tener por lo menos 2 n+1
2 = n + 1 vértices.
Contradicción

Proposición 4 El número mínimo de arcos en un grafo conexo G con n vértices


es n − 1

Demostración por inducción fuerte sobre m = |A|, el número de arcos.


Se prueba entonces que en un grafo conexo G, m ≥ n − 1

• Caso base. m = 0. Si no hay arcos, n = 1 y m ≥ n − 1.

• Supongamos que la proposición es cierta para m = 1, · · · , k y sea G un grafo


conexo con k + 1 arcos.
Sea e un arco cualquiera de G. El grafo G − e tiene n vértices y k arcos y hay
dos posibilidades:

i. G−e es conexo. Por hipótesis de inducción k ≥ n−1 y entonces k +1 ≥ n−1.

ii. G − e no es conexo y tiene dos componentes conexas G1 y G2 . Si k1 , n1 y


k2 , n2 son el número de arcos y de vértices en G1 y G2 respectivamente, por
hipótesis de inducción en las componentes conexas se tiene que k1 ≥ n1 − 1
y k2 ≥ n2 − 1. Así:
k1 + k2 ≥ n1 + n2 − 2
k1 + k2 + 1 ≥ n1 + n2 − 1
k+1≥n−1

pues k1 + k2 + 1 = k + 1 y n1 + n2 = n.

Proposición 5 Si δ(G) ≥ 2, entonces G contiene una trayectoria de longitud


δ(G) y un ciclo de longitud mayor o igual a δ(G) + 1

23
Grafos

Dem. Sea v0 v1 . . . vk una trayectoria maximal en G. Todos los vecinos del vértice
vk deben estar en la trayectoria, pues si alguno no lo está la trayectoria se podría
extender y no sería maximal. Por lo tanto k ≥ d(vk ) ≥ δ(G).
Sea i el valor mínimo para el que vi vk ∈ A. Entonces vi . . . vk vi es un ciclo de
longitud mayor o igual a d(vk ) + 1 ≥ δ(G) + 1.

Si denotamos con cc(G) al número de componentes conexas del grafo G, se tiene el


siguiente resultado:

Proposición 6 En todo grafo G = (V, A), cc(G) ≥ |V | − |A|

Demostración por inducción sobre n = |A|, el número de arcos.


Caso base n = 0
Si el grafo no tiene arcos, cc(G) = |V | y se cumple que cc(G) = |V | ≥ |V | − 0
Paso inductivo Supongamos que la propiedad es cierta para todo grafo con n arcos
y veamos que también es cierta para todo grafo con n + 1 arcos.
Sea G = (V, A) un grafo tal que |A| = n + 1. Sea uv cualquier arco del grafo y G0 el
grafo que resulta al eliminar ese arco. Por la hipótesis de inducción cc(G0 ) ≥ |V |−n.
Volviendo al grafo G pueden presentarse dos casos:

i. u y v están en la misma componente conexa de G0 . En este caso

cc(G) = cc(G0 ) ≥ |V | − n ≥ |V | − (n + 1)

la propiedad es cierta para G.

ii. u y v están en distintas componentes conexas de G0 . En este caso

cc(G) = cc(G0 ) − 1 ≥ |V | − n − 1 = |V | − (n + 1)

y en este caso también la propiedad es cierta para G.

En un grafo G = (V, A), si U ⊂ V , G[U ] denota el grafo con U como conjunto de


vértices y cuyos arcos son los arcos de G con ambos extremos en U .

Proposición 7 Para todo grafo conexo G existe una enumeración v1 , v2 , . . . , vn


de sus vértices tal que Gi := G[v1 , . . . , vi ] es conexo para i = 1, . . . , n

Demostración. Se escoge cualquier vértice del grafo como v1 .


Suponga inductivamente que ya se tiene una enumeración v1 , . . . , vi con la propiedad
indicada para algún i ≤ |V |. Se escoge un vértice v ∈ G − Gi . Como el grafo es
conexo, existe una trayectoria vT vi . Se escoge el último vértice de esta trayectoria
que esté en G − Gi como vi+1 .

24
Grafos

1.8 Componentes fuertemente conexas

En un digrafo la relación uT v no es simétrica. Pero si G = (V, A) es un digrafo, en


el conjunto de vértices V se puede definir una relación R0 así:
uR0 v si y solo si existe una trayectoria de u a v y una trayectoria de v a u.
Esta también es una relación de equivalencia y las clases de equivalencia de esta
relación son llamadas las componentes fuertemente conexas del digrafo. Si hay una
sola componente fuertemente conexa el digrafo se llama fuertemente conexo. El
digrafo reducido Ĝ = (V̂ , Â) es el digrafo que tiene como vértices las componentes
fuertemente conexas de G y cuyo conjunto de aristas se define así:
(û, v̂) ∈ Â si y solo si ∃(u, v) ∈ A | u ∈ û, v ∈ v̂

La figura 1.13 muestra un ejemplo de un digrafo y su grafo reducido.

Figura 1.13 Un Digrafo y el digrafo reducido.

En digrafos un problema importante es encontrar las componentes fuertemente


conexas. Los siguientes son dos algoritmos que solucionan el problema.

• Componentes fuertemente conexas I.

En este algoritmo primero se resuelve el problema de encontar la componente


conexa a la que pertenece un vértice dado. Dado un vértice u, se defininen los
conjuntos:
X + (u) = {v ∈ A | hay trayectoria de u a v}
X − (u) = {v ∈ A | hay trayectoria de v a u}

25
Grafos

Si ya se tienen estos conjuntos, la componente fuertemente conexa a la que


pertenece u, C(u), es
C(u) = X + (u) ∩ X − (u)
El siguiente es el seudocódigo de un algoritmo imperativo para calcular X + (u).
Con muy pocos cambios también se tiene un algoritmo para calcular X − (u).

ccf(G: grafo, u: vértice) : conjunto


X + (u)[1] := u total := 1 marcados := 0
Mientras marcados < total
marcados := marcados +1 v := X + (u)[marcados]
para cada (x, y) ∈ A
Si x = v y y ∈/ X + (u)
total := total +1; X + (u)[total] := y
fin para cada
fin mientras

Después de calcular C(u) se repite el procedimiento con vértices que no pertenez-


can a ninguna de las componentes fuertemente conexas ya encontradas.

• Componentes fuertemente conexas II.

Un segundo algoritmo se basa en la matriz de adyacencia del grafo. Si A es la


matriz de adyacencia de un grafo G, ya vimos que si Aki,j = mp entonces hay p
paseos que llevan del nodo i al nodo j en exactamente k pasos. Por lo tanto si
definimos la matriz C como 10

C = I ∨ A ∨ A2 ∨ · · · ∨ Am

donde m es el número de arcos del grafo, Cij será igual a 1 si y solo si hay una
trayectoria del vértice i al vértice j pues en el peor de los casos la trayectoria
que une estos vértices pasa por todos los arcos del grafo. Se incluye la matriz I
pues es posible llegar de un vértice a él mismo en 0 pasos. Por lo tanto la fila
i de la matriz C ∧ C t tendrá un 1 en la columna j si y solo si los vértices i y j
están en la misma componente fuertemente conexa.

10 Las operaciónes booleanas ∨ y ∧ consideran cualquier número distinto de 0 como 1 y se hacen


componente a componente.

26
Grafos

El problema consiste en calcular la matriz C pues para valores grandes de m se


requiere de una cantidad astronómica de operaciones aritméticas. Pero una inge-
niosa solución recurre a una idea del análisis matemático 11. La idea es convertir
la suma finita en una serie de matrices! Si se define la matriz D como
D = I + A + A2 + · · · + A k + · · ·

se tiene lo siguiente:
Cij = 0 si y solo si Dij = 0
Cij = 1 si y solo si Dij > 0
Obviamente la serie seguramente no es convergente. Pero de serlo, la matriz D
tendría la siguiente propiedad:
(I − A)D = D − AD
= I + A + A2 + · · · − A − A 2 − · · ·
=I

es decir (I − A)D = I, y entonces D = (I − A)−1


El problema de la convergencia de la serie se puede tratar redefiniendo la matriz
D como:
D = I + αA + (αA)2 + · · · + (αA)k + · · ·

tomando un valor pequeño para α (la matriz A es binaria), y así D = (I − αA)−1


El siguiente es un programa sencillo (ScalaLab) que implementa este algoritmo
usando un valor para α de 0.5:

(Definición de la matriz a de adyacencia)

var b = eye(n)
var d = inv(b - a)
var dt = d~
var c = zeros(n)
for (i<- 0 to n-1){ for (j<- 0 to n-1) c(i,j)= d(i,j)*dt(i,j)}

Para el digrafo de la figura 10 la matriz resultante es:

11 Graph Algorithms In The Language Of Linear Algebra. Jeremy Keper, John Gilbert. eds. Chapter
3. Charles M. Rader. Siam

27
Grafos

 
1.138 0.071 0.071 0.071 0.000 0.000 0.000 0.000 0.000 0.000 0.000
 0.071 1.138 0.071 0.071 0.000 0.000 0.000 0.000 0.000 0.000 0.000 
 
 0.071 0.071 1.138 0.071 0.000 0.000 0.000 0.000 0.000 0.000 0.000 
 
 0.071 0.071 0.071 1.138 0.000 0.000 0.000 0.000 0.000 0.000 0.000 
 
 0.000 0.000 0.000 0.000 1.306 0.163 0.163 0.000 0.000 0.000 0.000 
 
 0.000 0.000 0.000 0.000 0.163 1.306 0.163 0.000 0.000 0.000 0.000 
 
 0.000 0.000 0.000 0.000 0.163 0.163 1.306 0.000 0.000 0.000 0.000 
 
 0.000 0.000 0.000 0.000 0.000 0.000 0.000 1.000 0.000 0.000 0.000 
 
 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 1.306 0.163 0.163 
 
 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.163 1.306 0.163 
0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.163 0.163 1.306

1.9 k−conectividad

En las aplicaciones de la teoría de grafos surgen problemas importantes como los


siguientes:

• Si u, v ∈ V , ¿Cuantas trayectorias uT v internamente disyuntas hay? ¿Cuantas


de longitud menor o igual a un valor dado c?

• Si (u1 , v1 ) . . . (uk , vk ) son parejas de vértices, ¿existen trayectorias T1 , . . . , Tk


internamente disyuntas tal que Ti = ui T vi ?

Si G = (V, A) es un grafo conexo, un subconjunto V 0 de V es llamado un corte por


vértices de G si G − V 0 es no conexo. Si |V 0 | = k el subconjunto también es llamado
un k−corte por vértices
La conectividad κ(G) de un grafo conexo G = (V, A) se define, para el grafo completo
Kn , como n − 1 y para los demás casos como:
κ(G) = min{|T | : T es un corte por vértices}

Si S, S 0 es una partición de V, [S, S 0 ] denota al conjunto de arcos en G que tienen


un extremo en S y el otro en S 0 , llamado un corte por arcos de G, e igualmente si
su cardinalidad es k también es llamado un k−corte por arcos
La arco-conectividad λ(G) del grafo se define como:

λ(G) = min{|T | : T es un corte por arcos}

El grafo G es r−conexo si κ(G) ≥ r y es r− arco conexo si λ(G) ≥ r

28
Grafos

Si u, v ∈ V , un subconjunto X de A es llamado un arco separador de u y v si toda


trayectoria uT v contiene algún arco de X.
Un subconjunto Y de V es llamado un vértice separador de u y v si toda trayectoria
uT v contiene algún vértice de Y.

Proposición 8 La desigualdad de Whitney


En todo grafo G no trivial
κ(G) ≤ λ(G) ≤ δ(G)

Dem. Supongamos primero que λ(G) > δ(G) y sea v un vértice de grado δ(G). Si
se eliminan los δ(G) arcos incidentes con v el grafo se desconecta y por lo tanto
λ(G) ≤ δ(G); contradicción.
Supongamos ahora que κ(G) > λ(G). Sea S un conjunto de arcos con |S| = λ(G)
y tal que G − S es no conexo. Se pueden eliminar λ(G) vértices de G escogidos de
manera que el grafo se desconecta. Por lo tanto κ(G) ≤ λ(G); contradicción.

Si κ(G) = λ(G) = δ(G) se dice que el grafo tiene conectividad máxima

Teorema 1 [Whitney] Sea G un grafo tal que |V | ≥ 3. G es 2−conexo si


y solo si para todo par de vértices distintos u, v existen dos trayectorias de u a v
internamente disyuntas.

Dem. ⇐) Sea w un vértice cualquiera de G y u y v dos vértices distintos de G − w.


Hay dos trayectorias uT1 v y uT2 v internamente disyuntas en G y w puede estar a
lo más en una de ellas. Por lo tanto si se elimina a w el grafo no se desconecta, i.e.,
no hay vértices de corte y así el grafo es 2−conexo.

⇒) Supongamos que el grafo es 2−conexo y sean u, v ∈ A. La demostración se


hace por inducción en d(u, v).
Caso Base Si d(u, v) = 1.
κ(G) ≤ λ(G) y κ(G) ≥ 2 implican que λ(G) ≥ 2. Por lo tanto G − uv es conexo y
se tienen dos trayectorias de u a v internamente disyuntas:

• uv.

• Una trayectoria uT v en G − uv

Paso inductivo Si d(u, v) > 1.


Sea w el vértice adyacente a v en una trayectoria uT v mínima. Por hipótesis de
inducción, en G hay dos trayectorias P : uT1 w y Q : uT2 w internamente disyun-
tas. Como G − w es conexo, existe una trayectoria R : uT v en G − w. Hay dos
posibilidades:

29
Grafos

1. R es internamente disyunta con P (o con Q). Entonces en G hay dos trayectorias


de u a v internamente disyuntas: R y P v (o Qv)

2. R no es internamente disyunta ni con P ni con Q. Sea z el último vértice que está


en R ∩ (P ∪ Q). Supongamos que z ∈ P . Entonces en G hay dos trayectorias de
u a v internamente disyuntas:

− Seguir P hasta llegar a z, luego continuar por la trayectoria R.

− Qv

El siguiente teorema generaliza el anterior resultado:

Teorema 2 Un grafo no trivial G es k−conexo si y solo si para cada par de


vértices distintos u, v hay por lo menos k trayectorias uT v internamente disyuntas.

Del teorema de Whitney se deduce que un grafo con por lo menos 3 vértices es
2−conexo si y solo si cualquier par de vértices pertenecen a un ciclo común.

Hay unos teoremas similares, como los de Menger en la versión vértices y en la


versión arcos. Su demostración se puede consultar en [1]

Teorema 3 Sea G un (di)grafo y s, t ∈ V vértices no adyacentes. El número


máximo de trayectorias internamente disyuntas de s a t es igual a la mínima cardi-
nalidad de un conjunto vértice separador para s y t.

Teorema 4 Sea G un (di)grafo y s, t ∈ V vértices no adyacentes. El número


máximo de trayectorias disyuntas por arcos de s a t es igual a la mínima cardinalidad
de un conjunto arco separador para s y t.

El primer algoritmo de la siguiente sección está relacionado con la algunos de los


anteriores temas,

30
Grafos

1.10 Grafos con peso. Tres algoritmos

Un grafo con peso es un grafo en el que también se tiene una función


δ : A −→ R
El número real δ(a) es llamado el peso del arco a. Los siguientes son tres ejemplos
clásicos de problemas en los que aparecen grafos con peso.
El problema del corte mínimo
Un corte en un grafo G = (V, A) es una partición de V en dos subconjuntos no
vacíos X, Y . Un arco uv ∈ A cruza el corte si u ∈ X, v ∈ Y o v ∈ X, u ∈ Y .

Figura 1.14 Un corte en un grafo.


Problema : Encontrar en un grafo dado un corte con el número mínimo de arcos
cruzando el corte.
Un resultado interesante es que hay un algoritmo probabilístico para tratar este
problema que usa como operación básica la contracción de arcos. Esta operación
consiste en elegir un arco uv del grafo y unir sus dos vértices en uno solo. El arco que
resulta del nuevo vértice con el mismo se elimina. El resultado es un grafo en el que
pueden aparecer arcos paralelos (llamado un multigrafo) que se puede representar
como un grafo simple, denotado con G/uv, si arcos paralelos se reducen a un solo
arco, asignandole a este arco un peso igual al número de arcos unidos. El número
de un corte se calcula ahora sumando los pesos de los arcos en el corte.

Figura 1.15 Contracción de arcos.

31
Grafos

Una primera observación importante es que el tamaño del corte mínimo en G/uv es
por lo menos tan grande como el tamaño del corte mínimo en G, pues todo corte en
G/uv tiene su correspondiente corte es G con igual cardinalidad. La idea principal
del algoritmo consiste entonces en hacer contracciones hasta tener un grafo con un
solo arco y por lo tanto con un único corte.
El algoritmo Min-Cut

1. G0 ← G

2. i = 0

3. Mientras Gi tenga más de dos vértices:

a. Escoja aleatoriamente un arco ai de Gi .

b. Gi+1 ← Gi /ai

c. i ← i + 1

4. Sea (S, V − S) el corte de G correspondiente al único corte en Gi

Figura 1.16 Aplicando contracciones.

32
Grafos

Pero es claro, como se ve en la figura, que el tamaño de ese único corte no necesaria-
mente corresponde al tamaño del corte mínimo del grafo original G. ¿ Qué utilidad
tiene entonces este procedimiento? Para garantizar que el tamaño del corte único
sea el mismo que el del corte mínimo de G se deberían contraer arcos que no estén
en un corte minimal; pero para hacer esto hay que conocer el corte minimal de G!
La clave está en calcular la probabilidad de que el tamaño del único corte final
sea el del corte mínimo en G. Si G tiene un corte mínimo de tamaño k, entonces
|A| ≥ kn/2 y por lo tanto la probabilidad de que un arco elegido aleatoriamente esté
en un corte mínimo es como máximo 2/n. Si la elección aleatoria continua hasta
tener un grafo G0 con solamente dos vértices se tiene el siguiente resultado:

La probabilidad de que el tamaño del corte de G0 sea el mismo de un corte mínimo


2
en G es ≥ n(n−1)

Saber, por ejemplo, que para un grafo con 100 vértices (que es un grafo pequeño)
la probabilidad de que Min-Cut retorne una solucíon correcta es mayor a 0,0001980
no parece de gran utilidad. ¿Cómo hacer que esa probabilidad sea mayor? Para
aumentar la probabilidad de obtener un corte mínimo correcto, se puede ejecutar
Min-Cut varias veces guardando el mínimo de todas las ejecuciones . El algoritmo
MinCutRep consiste en ejecutar Min-Cut n(n − 1) veces, y se tiene entonces este
resultado

La probabilidad de que MinCutRep falle en retornar un corte mínimo es < 0.14

Para probar este resultado se usa la siguiente desigualdad:


1 − x ≤ e−x si 0 ≤ x ≤ 1

Así:
2 n(n−1) − 2 n(n−1)
1− ≤ e n(n−1) = e−2 ' 0.14
n(n − 1)

El algoritmo de Dijkstra

Consideremos un grafo con pesos positivos. Dada una trayectoria T entre dos vér-
tices u, v, se define el costo de esa trayectoria, c(T ), como
X
c(T ) = δ(ai )
ai ∈T

Un problema interesante y con numerosas aplicaciones es el siguiente: Dado un


grafo con pesos positivos y un vértice inicial s, encontrar la trayectoria entre s y
otro vértice cualquiera v que tenga costo mínimo.

33
Grafos

El siguiente algoritmo, debido al matemático Edsger Dijkstra (1930 - 2002), calcula


las trayectorias de costo mínimo desde s hasta cualquier otro vértice en la compo-
nente conexa a la que pertenece s. El algoritmo usa tres estructuras; X, donde
se guardan los vértices que se van procesando; A, que guarda los valores de las
trayectorias de costo mínimo y B que guarda las trayectorias de costo mínimo.

Dijkstra(G: grafo, δ)
Inicialización.

1. X=[s]; A[s] = 0; B[s] = ∅

2. Mientras X 6= V ,
De todos los arcos (v, w) ∈ A tal que v ∈ X, w ∈
/X

a. Escojer aquel (v ∗ , w∗ ) que minimice A[v] + δ(v ∗ w∗ ) Criterio voraz

b. Agregar w∗ a X.

c. Hacer A[w∗ ] = A[v ∗ ] + δ(v ∗ w∗ ).

d. Hacer B[w∗ ] = B[v ∗ ] ∪ (v ∗ , w∗ )

Es posible que en el paso 2a del algoritmo se presenten empates, en cuyo caso se


puede escojer cualquiera de los arcos que minimiza. Con el ejemplo elemental de la
figura 1.17 se puede mostrar como opera el algoritmo

Figura 1.17

34
Grafos

Un resultado parcial del algoritmo se muestra en la figura 1.18 y en la tabla 1.2.

Figura 1.18 Aplicando el criterio voraz de Dijkstra.

X s a c b d

A s a c b d
0 4 5 7 10

B s a c b d
∅ sa sc sc, cb sa, ad
Tabla 1.2 Resultado parcial
del algoritmo de Dijkstra.

Y el resultado final se muestra en la tabla 1.3.

X s a c b d e g f h

A s a c b d e g f h
0 4 5 7 10 12 14 14 16

B s a c b d e g f h
∅ sa sc sc, cb sa, ad sc, cb, be sa, ad, dg sa, ad, df sa, ad, dg, gh

Tabla 1.3 Resultado final del algoritmo de Dijkstra.

35
Grafos

Usando un argumento inductivo en el número de iteraciones se puede probar que el


algoritmo de Dijkstra efectivamente calcula la trayectoria de costo mínimo desde s
hasta cualquier otro vértice v.

Sea L[v] el costo de la ruta de costo mínimo desde s hasta v. Se debe probar que
A[v] = L[v].
Caso base. X = [s]. A[s] = L[s] = 0.
Hipótesis inductiva: ∀v ∈ X A[v] = L[v] y B[v] es la ruta de menor costo desde
s hasta v.
En el siguiente paso el algoritmo selecciona un nuevo vértice w∗ usando el criterio
voraz de Dijkstra y hace A[w∗] = A[v∗] + δ(v ∗ w∗). Probemos que toda trayectoria
s hasta w∗ tiene un costo mayor o igual a ese valor.
Sea P cualquier trayectoria desde s hasta w∗. En algún momento la trayectoria P
debe pasar del conjunto X al conjunto V − X, digamos en el arco yz. El criterio
voraz de Dijkstra asegura que
A[v∗] + δ(v ∗ w∗) ≤ A[y] + δ(yz) ≤ A[y] + δ(yz) + c(zw∗)

donde c(zw∗) es el costo de ir del vértice z al vértice w∗ que no puede ser negativo.
Por lo tanto, usando la hipótesis inductiva:
L[w∗] = L[v∗] + δ(v ∗ w∗)

El algoritmo de Dijkstra debe agregar cada vértice al conjunto X, y para agregar


un vértice al conjunto X hace una búsqueda en los arcos para encontrar el elegible.
Por lo tanto, una implementación directa del algoritmo como se ha visto tendría
complejidad O(nm). Pero los algoritmos se presentan aquí en versiones que buscan
mostrar claramente las ideas detrás de su operación. Usualmente no son las versiones
mas eficientes. Para el caso del algoritmo de Dijkstra, usando estructuras de datos
apropiadas se puede reducir su complejidad. Una versión del algoritmo que usa
colas de prioridad tiene una complejidad O(|A| log |A|) y otra versión que usa pilas
de Fibonacci tiene una complejidad O(|A| + |V | log |V |).

Trayectorias de costo mínimo con programación dinámica

Los problemas en teoría de grafos dan origen a algoritmos que, en muchas ocasiones,
a su vez crean nuevas ideas matemáticas. Consideremos un grafo con pesos. En este
caso su matriz de adyacencia C no es binaria; ahora la componente cij de esta matriz
corresponde al peso del arco que conecta los vértices vi , vj . Si los vértices no son
adyacentes cij no es cero, es ∞.
Entonces las componentes de la i−esima fila de esa matriz, ci1 , ci2 , . . . cin son los
pesos de los arcos del vértice vi a todos los demás vértices. Y las componentes de
la j−esima columna de esa matriz, c1j , c2j , . . . cnj son los pesos de los arcos que de

36
Grafos

todos los vértices llegan al vértice vj . Esto se puede ilustrar con la figura 1.19 (no
todos los arcos necesariamente existen)

Figura 1.19 Arcos


en un grafo con pesos.

Entonces si no hay conexión directa entre vi y vj , la trayectoria de menor costo de


longitud 2, si la hay, tendrá un costo
mink {cik + ckj }

y será vi − vk0 − vj donde k 0 = argmink {cik + ckj }. Si no hay trayectoria de longitud


2 se puede proceder recursivamente. En esto se basa el siguiente algoritmo 12.
El cálculo de la ruta de costo mínimo entre dos vértices cualquiera de un grafo se basa
en operaciones con matrices y programación dinámica. Con base en lo anteriormente
expuesto, para este algoritmo se define la siguiente operación entre matrices:
Dadas dos matrices M y N , la matriz D = M min. + N se define así:
dij = (M min. + N )ij := min{mik + nkj }
k

Por ejemplo:
     
0 3 1 2 4 3 2 2 3
A = 2 1 0B = 0 1 1 A min. + B =  1 1 2 
3 2 1 2 1 3 2 2 3

12 Graph Algorithms In The Language Of Linear Algebra. Jeremy Keper, John Gilbert. eds. Chapter
3. Charles M. Rader. Siam

37
Grafos

Sea G = (V, A) un digrafo con |V | = n, |A| = m y sea C la matriz de los costos o


pesos (no negativos) asociados a los arcos. A cii se le asigna el valor 0 y si no hay
un arco uniendo al vértice i con el vértice j, a cij se le asigna el valor ∞.
Como cik es el costo de la conexión del vértice i con el vértice k y ckj es el costo
de la conexión del vértice k con el vértice j, entonces cik + ckj es el costo de ir del
vértice i al vértice j pasando por el vértice k. Por lo tanto, como la minimización
incluye los casos k = i y k = j, (C min. + C)ij es igual al menor costo para ir del
vértice i al vértice j en no más de dos pasos.
Se define recursivamente la matriz exponencial diamante así:
C 1 = C C n = C min. + C (n−1)

Se puede probar por inducción que (An )ij es el valor de la trayectoria de menor
costo para ir del vértice i al vértice j en n pasos (teniendo presente que un paso
puede ser ir de un vértice a él mismo).
Según el principio de Bellman, todas las subtrayectorias de una trayectoria óptima
deben ser también óptimas. Aplicando este principio se deduce que la exponencial
diamante tiene una propiedad similar a la exponencial usual:
A(p+q) = Ap min. + Aq

El ejemplo elemental en la figura 1.20 ilustra la operación diamante con matrices:

Figura 1.20 Un ejemplo


del algoritmo diamante.
    
0 5 6 ∞ ∞ 0 5 6 ∞ ∞ 0 5 6 10 16
 5 0 ∞ 8 ∞   5 0 ∞ 8 ∞   5 0 11 8 10 
C 2
    
 6 ∞ 0 4 10   6 ∞ 0 4 10  =  6 11 0 4 6 
=    
 ∞ 8 4 0 2   ∞ 8 4 0 2   10 8 4 0 2 
∞ ∞ 10 2 0 ∞ ∞ 10 2 0 16 10 6 2 0

38
Grafos

La matriz C 2 contiene los valores de las trayectorias de costo mínimo de longitud


2 entre cada par de nodos. Nótese que el valor de c35 cambió de 10 a 6 pues hay
una trayectoria de longitud 2 entre los vértices c y e más barata que el costo de la
conexión directa. Puede comprobarse también, calculando C 3 que la componente
15 de C 2 cambia de 16 a 12 pues hay una trayectoria de longitud 3 entre los nodos
a y e más barata que las anteriores que tenían menos arcos.

Para obtener no solamente el valor de la trayectoria de menor costo sino también


la trayectoria misma, en la definición de la operación min.+ se puede agregar una
matriz en la que se guardan los vértices para los que la suma es mínima:
[C, D] = A min. + B
Cij := min{aik + bkj }
k
Dij := argmin {aik + bkj }

1.11 Árboles

Un grafo sin ciclos es llamado un bosque. Un árbol es un grafo conexo sin ciclos.
Un arco en un grafo conexo es llamado un puente si al eliminar el arco el grafo
resulta no conexo.

Proposición 9 En todo árbol T, todos sus arcos deben ser puentes

Dem. Supongamos que en algún árbol T hay un arco vw que no es puente. Entonces
al eliminar este arco el grafo sigue siendo conexo y por lo tanto debe existir alguna
trayectoria P = w, v2 , . . . , v. Pero entonces al agregar el arco vw al inicio de esta
trayectoria se obtendría un ciclo en el árbol original. Contradicción.

Un vértice de grado 1 en un grafo G es llamado un vértice final o una hoja.

Proposición 10 Todo árbol con por lo menos 2 vértices tiene por lo menos dos
hojas.

Dem. Sea T=(V, A) un árbol y sea P = v1 , v2 , . . . , vk una trayectoria de longitud


máxima. La longitud de la trayectoria es por lo menos 1 de modo que v1 6= vk . Se
puede probar por contradicción que v1 y vk deben ser hojas. Supongamos que v1 no
es hoja, entonces existe un arco v1 v con v 6= v2 y dos posibilidades para v:
Si v ∈ P , entonces v = vi para algún i ≥ 3; pero entonces v1 , v2 , . . . , vi , v1 formaría
un ciclo y el árbol no puede tener ciclos.
/ P , entonces P 0 = v, v1 , v2 , . . . , vk sería una trayectoria de mayor longitud,
Si v ∈
contradiciendo la hipótesis.

39
Grafos

Proposición 11 Si T es un árbol entonces si se agrega cualquier arco uv se forma


un (único) ciclo

Dem. Sean u, v dos vértices no adyacentes en el árbol T. Como T es conexo, existe


una única trayectoria uT v en el árbol. Y si se agrega el nuevo arco vu al final de
esa trayectoria se forma un ciclo.

Proposición 12 En todo árbol T = (V, A), |V | = |A| + 1

Dem. Usando inducción fuerte.


Si |V | = 1, entonces |A| = 0 y el resultado se cumple.

Supongamos que la propiedad es cierta para todo árbol con menos de n vértices y
sea T un árbol con n vértices.
Sea a un elemento cualquiera de A. Como a es puente, T − a tiene dos componentes
conexas que son árboles T1 = (V1 , A1 ), T2 = (V2 , A2 ). Por hipótesis de inducción:
|v1 | = |A1 | + 1 |v2 | = |A2 | + 1

sumando estas dos igualdades


|V1 | + |V2 | = |A1 | + 1 + |A2 | + 1

pero |V1 | + |V2 | = |V | y |A1 | + 1 + |A2 | = |A| (se suma 1 por la arista a que se
eliminó) y por o tanto |V | = |A| + 1

Proposición 13 En un grafo G sin ciclos, si |V | = |A| + 1, entonces el grafo es


un árbol

Dem. Hay que probar que el grafo es conexo. Supongamos que G tiene componentes
conexas Gi = (Vi , Ai ), i = 1, . . . , k.
Cada componente conexa es un árbol (no hay ciclos) y por lo tanto
|Vi | = |Ai | + 1, i = 1, . . . , k

pero
k
X k
X
|V | = |Vi | y |A| = |Ai |
i=1 i=1

y entonces:
k
X k
X
n − 1 = |A| = |Ai | = |Vi | − 1 = n − k
i=1 i=1

y por lo tanto k = 1.

40
Grafos

El código de Prüfer

Obviamente un árbol se puede representar usando matrices o listas de adyacencia.


Pero existen formas interesantes de representar árboles, en particular una llamada
el código de Prüfer.
Si se tiene un árbol con n vértices, estos se pueden etiquetar con los números de 0
a n − 1. El nodo etiquetado con 0 va a ser especial y lo llamaremoa raíz.
Ahora se puede hacer una lista de los arcos del árbol escribiendo, para cada arco,
primero el vértice que está más lejos de la raíz y luego el otro vértice (que llamaremos
su padre). Si se organiza esto en un arreglo de dos filas podemos ver lo siguiente:

i. En la primera fila no aparece el 0.

ii. En la primera fila aparecen todos los vértices, menos el cero, exactamente una
vez.

La razón de lo primero es que 0 no es hijo de ningún vértice y la de lo segundo es


que cada vértice distinto de 0 tiene un único padre. Si los vértices de la primera fila
están ordenados se puede omitir esa fila y dejar solamente la segunda. Por lo tanto
es posible representar un árbol como una sucesión de n − 1 números enteros y esto
tiene un costo de (n − 1)dlog2 ne bits. La figura 1.21 muestra un ejemplo.

Figura 1.21 El código padre.

Sin embargo este código (llamado el código padre) no es óptimo pues no toda sucesión
de n − 1 enteros corresponde a un árbol.

Pero se puede hacer la siguiente variante. Los vértices que aparecen en la primera
fila del código padre se pueden ordenar de la siguiente forma: Se escoje un vértice
de grado 1 (distinto de 0) con la menor etiqueta, se pone en el arreglo y se eliminan

41
Grafos

vértice y arco del árbol. Se continua así hasta listar todos los arcos. El resultado
obtenido es llamado el código de Prüfer extendido. El siguiente es un ejemplo.

Figura 1.22 Árbol etiquetado..

1 2 5 6 4 8 9 10 11 3 12 13 14 7
11 11 4 4 3 3 0 0 3 0 7 7 7 0
Tabla 1.4 Código de Prüfer extendido.

Al construir el código de Prüfer extendido suceden dos cosas:

i. El último elemento de la segunda fila debe ser 0.

ii. Los vértices en la primera fila no aparecen en el orden natural.

El segundo de los anteriores resultados parece ser una desventaja; ¿En qué orden
deben ir los vértices? Pero este código tiene dos propiedades muy interesantes

En el código de Prüfer extendido, la segunda fila determina a la primera


Teniendo presente que en una misma posición en la primera y segunda filas no puede
aparecer el mismo número, la forma en que la segunda fila determina a la primera
es esta:
Cada entrada en la primera fila del código de Prüfer es el menor entero tal que:

i. No aparece en la primera fila antes de ella.

ii. No aparece en la segunda fila después de ella.

De modo que el árbol de la figura 1.22 se puede guardar simplemente como


11 11 4 4 3 3 0 0 3 0 7 7 7 0

Sorprendente!!

42
Grafos

Y la segunda propiedad es:


Toda sucesión de números entre 0 y n − 1 de longitud n − 2 es el código de Prüfer
de algún árbol con n vértices. Cada código de Prüfer puede verse como un número
natural de n − 2 digitos escrito en base n.
De lo anterior se deduce inmediatamente un resultado cuya prueba por otros medios
es bastante más difícil:

Teorema de Cayley
Para un conjunto de n vértices hay nn−2 posibles árboles

Árboles con raíz y árboles plantados

Un árbol con raíz, denotado (T, r), es un árbol en el que hay un vértice distinguido
r llamado la raíz.

Figura 1.23 Árbol con raíz.

Dos árboles con raíz (T, r), (T 0 , r0 ) son isomorfos, denotado con T ' T 0 , si existe
un isomorfismo de grafos φ : T → T 0 tal que φ(r) = r0 .
Un árbol plantado es un árbol con raíz en el que los hijos de cada vértice están en
algún orden lineal. Un isomorfismo entre árboles plantados, denotado con T ∼ = T 0 , es
un isomorfismo de árboles con raíz que preserva el orden en los hijos de cada vértice.
Dos árboles pueden ser isomorfos como árboles con raíz, pero no ser isomorfos como
árboles plantados como se muestra en la figura 1.24.
A cada árbol plantado se le puede asignar recursivamente un código binario de la
siguiente manera:

i. A cada hoja (que no sea raíz) se le asigna el código 01

43
Grafos

Figura 1.24 T ' T 0 , pero no T ∼


= T0 .

Figura 1.25 Codificación


de un árbol plantado .

ii. Sea v un vértice con hijos v1 , v2 , . . . , vk (ordenados de izquierda a derecha). Si


Ci es el código de vi , entonces el vértice v tiene código 0C1 C2 . . . Ck 1.

Nótese que en el código resultante debe haber un número par de bits y el número
de ceros debe ser igual al número de unos. Pero esta no es una condición suficiente
para que una cadena de bits sea el código de un árbol plantado como se puede ver
con la cadena 0001110000101111.
Toda codificación debe permitir reconstruir un árbol a partir de un código dado.
Con el siguiente método recursivo se puede reconstruir el árbol:

i. Si el código es 01 es una hoja.

44
Grafos

ii. Todo código de longitud 2(n + 1) n > 1 debe ser de la forma 0A1. A a su vez
debe ser de la forma A1 . . . At . A1 es el segmento inicial de A más corto con
igual número de ceros y unos, y así sucesivamente.

La anterior codificación se puede extender para el caso de árboles con raíz cambiando
el segundo paso de la codificación así:
ii) Suponga que cada hijo w de un vértice v tiene asignado código A(w). Se enumeran
los hijos de v como w1 w2 . . . wt de modo que (usando el orden lexicográfico):
A(w1 ) ≤ A(w2 ) ≤ · · · ≤ A(wt )

y a v se le asigna el código 0A1 A2 . . . At 1 donde Ai = A(wi )

Se puede mostrar el siguiente resultado:


Dos árboles con raíz son isomorfos si y solo si tienen el mismo código

Dado un vértice v ∈ V en un grafo G, se define la excentricidad de v, exG (v), como:


ex(v) = max{d(v, w)|w ∈ V }

El centro de un grafo G es el conjunto C(G) formado por todos los vértices de V


con excentricidad mínima (llamada radio).

Proposición 14 En todo árbol T , C(T ) tiene máximo dos vértices.

Demostración
Si |V | = 2, C(G) = G.
Si no, sea T 0 = (V 0 , A0 ) el árbol resultante al eliminar todas las hojas de T .
V 0 = {v ∈ V |d(v) > 1} A0 = {vw ∈ A|d(v) > 1, d(w) > 1}

V 0 6= ∅, pues no todos los vértices de T pueden ser hojas. Se tiene que:


exT (v) = exT 0 (v) + 1 C(T ) = C(T 0 )

Si |V 0 | ≥ 3 se repite el procedimiento. Al eliminar una hoja un árbol no se puede


desconectar, de modo que si C(T ) = {u, v}, u y v deben ser adyacentes.

Codificación binaria de un árbol

i. Si C(T ) = {v} el código de T es el código del árbol con raíz (T, v).

ii. Si C(T ) = {u, v}, T − uv tiene dos componentes conexas T1 , T2 . Sea A el código
de (T1 , u) y B el código de (T2 , v)
Si A ≤ B, el código de T es el de (T, u)
Si no, el código de T es el de (T, v)

45
Grafos

1.12 Árboles de cubrimiento

Dado un grafo G = (V, A), todo árbol A = (V, A0 ) subgrafo de G es llamado un


árbol de cubrimiento 13 de G.

Proposición 15 Todo grafo conexo tiene un árbol span

La anterior proposición parece más que obvia. Sin embargo vamos a mirar tres
demostraciones diferentes con el fin de analizar sus diferencias.

Demostración 1. Sea T = (V, A0 ) un subgrafo conexo de G con el número mínimo


de arcos. T no puede tener ciclos pues, supongamos que existe un ciclo
v0 v1 − v1 v2 − · · · − vn v0

en T. ¿Qué pasa si se elimina el arco vn v0 ? Si dos vértices x, y del grafo estaban


unidos por una trayectoria que no contenía este arco, siguen estando conectados. Y
Si los vértices x, y del grafo estaban unidos por una trayectoria que si contenía este
arco, ellos permanecen unidos por una trayectoria que contiene al resto del ciclo.
Se tendría entonces un subgrafo conexo de G con menos arcos, contradiciendo la
hipótesis.

La anterior demostración es de la clase de demostraciones llamadas no constructivas.


El argumento es correcto pero, ¿la podemos usar para, si nos dan un grafo conexo G,
encontrarle un árbol de cubrimiento? El subgrafo conexo de con el número mínimo
de arcos obviamente (¿si es obvio?) debe existir. Pero, ¿cómo lo construimos?

Demostración 2. Sea G un grafo conexo. Si G no tiene ciclos, es su propio árbol


de cubrimiento. Si G contiene un ciclo, elimine un arco de ese ciclo. El grafo sigue
siendo conexo, como se probó en la anterior demostración. Si el grafo resultante no
tiene ciclos, es un árbol de cubrimiento de G. Si no, continue con el procedimiento
hasta llegar a un grafo conexo y sin ciclos con todos los vértices del grafo pues el
procedimiento elimina arcos pero no vértices.

Esta demostración parece más constructiva ya que indica un procedimiento a seguir.


Pero su idea principal en encontrar ciclos en grafos y no es evidente como hacer esto.

Demostración 3. Sea G = (V, A) el grafo. Se ordenan arbitrariamente los arcos de


G en una sucesión a1 , . . . am . Se define A0 = ∅ y:

13 El nombre en inglés es spanning tree.

46
Grafos


Ai−1 ∪ {ai } Si (V, Ai−1 ∪ {ai })no tiene ciclos
Ai =
Ai−1 En otro caso
El algoritmo termina cuando |Ai | = n − 1 o cuando i = m. En el primer caso
T = (V, Ai ) es un árbol de cubrimiento. Si el algoritmo termina con k = |Ai | < n−1
el grafo es no conexo con n − k componentes.
El anterior es un algoritmo para encontrar un árbol de cubrimiento. Existen métodos
computacionalmente muy eficientes para verificar la condición: Si (V, Ai−1 ∪ {ai })
no tiene ciclos. Y se puede demostrar que es correcto (ver [5]).
Los algoritmos para recorrer grafos BFS y DFS también se pueden modificar fácil-
mente para construir árboles de cubrimiento (ver [6], cap 5).

Un problema importante aparece cuando el grafo conexo es también un grafo con


pesos. El problema consiste en encontrar un árbol de cubrimiento óptimo, que
usualmente es un árbol de cubrimiento para el que la suma total de pesos es mínima.
Los siguientes dos algoritmos resuelven el problema.
El algoritmo de Kruskal

kruskal[G=(V, A)]

i. Ordenar la lista de arcos por pesos, de menor a mayor. [e1 , . . . , e|A| ]

ii. j:=1; T := ∅; k:= 0

iii. Hasta que k = |V | − 1 o j > |A| haga


si T ∪ ej es aciclico,
T := T ∪ ej
k := k + 1
j := j + 1

iv. si k = |V | − 1 retornar T; sino retornar fallo

Este es de la clase de algoritmos llamados voraces. Una forma de ver porqué el


algoritmo de Kruskal efectivamente da como resultado un arbol de cubrimiento
óptimo es la siguiente: Sea T un árbol de cubrimiento cualquiera en un grafo con
pesos G = (V, A). Para cada a ∈ A − T sea Ca el conjunto de arcos que pertenecen
a la única cadena en T que une los extremos de a. Por ejemplo, en el grafo de la
figura 1.26 con el arbol de cubrimiento indicado
C8,11 = {8 − 5, 5 − 9, 9 − 11}

47
Grafos

Figura 1.26

Si a ∈ T , T − a está formado por dos árboles disjuntos. Sea Ωa el conjunto de arcos


en G − T que tienen un extremo en uno de esos árboles y el otro extremo en el otro
árbol. En el mismo ejemplo.
Ω5,9 = {1 − 2, 5 − 2, 5 − 6, 8 − 9, 8 − 11}

Los siguientes son dos hechos a resaltar: Si a ∈ G − T , si se borra cualquier arco


de Ca de T y se agrega a, se obtiene otro árbol de cubrimiento. Y si se borra
cualquier arco a ∈ T y se agrega cualquier arco de Ωa también se obtiene otro árbol
de cubrimiento. De esto se deduce el siguiente resultado:

Teorema 5 Si G es un grafo con peso, T es un árbol de cubrimiento minimal


si y solo si :

i. Para todo a ∈ A − T , δ(a) ≥ maxa0 ∈Ca δ(a0 )

ii. Para todo a ∈ T , δ(a) ≤ mina0 ∈Ωa δ(a0 )

Se puede ver que el algoritmo de Kruskal obliga a que se cumpla la primera condición.
Una variante del algoritmo de Kruskal consiste en ir borrando arcos del grafo, esco-
giendo siempre para borrar al más costoso y manteniendo la conexidad.

Otro algoritmo que resuelve el mismo problema es el algoritmo de Prim. La idea de


este algoritmo consiste en ”hacer crecer” a T empezando con un árbol con un solo

48
Grafos

vértice y en cada paso añadir una nueva hoja u a T hasta que todos los vértices
se hayan unido. u se escoje de modo que el arco que lo conecta a T (el único arco
en la estructura E) sea el de peso mínimo entre los arcos que conectan un vértice
de T con los vértices que aun no estan en T. Nuevamente la versión del algoritmo
que se presenta acá muestra claramente la idea tras el algoritmo. Existen versiones
diferentes, usando por ejemplo la matriz de pesos (ver [6]).

El algoritmo Prim

PRIM(G,l: T)

1. Para todo v ∈ V haga L[v] = ∞

2. Escoja un vértice s ∈ V
L[s] ← 0
E[s] ← ∅
T EM P ← V
T ←∅

3. Mientras T EM P 6= ∅ :

a. Escoja un vértice u ∈ T EM P con L[u] mínimo.

b. T EM P ← T EM P − u

c. T ← T ∪ E[u]

d. Para todo uv ∈ A:
Si v ∈ T EM P y L[v] > l(uv)
L[v] ← l(uv)
E[v]←{ uv }

4. T

La figura 1.27 muestra un ejemplo de un grafo con pesos y el árbol resultante al


aplicar el algoritmo de Prim. La tabla 1.5 muestra los valores finales en las estruc-
turas de datos usadas.
Nótese que para este algoritmo no existe la condición de que los pesos no sean
negativos. La anterior versión del algoritmo de Prim y una demostración de que
el árbol T generado por el algoritmo de Prim es un árbol span minimal se pueden
consultar en [7].

49
Grafos

Figura 1.27 Un grafo y el arbol


span resultante con el algoritmo Prim.

L v4 v2 v3 v5 v6 v7 v1 v8
0 6 5 6 3 5 4 4

E v4 v2 v3 v5 v6 v7 v1 v8
∅ v1v2 v4v3 v4v5 v5v6 v6v7 v3v1 v6v8
Tabla 1.5 Estructuras de datos resultantes con el algoritmo Prim

1.13 Conjuntos independientes y cubrimiento por vértices

Un subconjunto S de V en un grafo es llamado un conjunto independiente de vértices


si ningún par de vértices del conjunto son adyacentes. El número de vértices de un
conjunto independiente de tamaño máximo en un grafo es llamado su número de
independencia, ind(G)
Un cubrimiento por vértices de G es un subconjunto S de V tal que

50
Grafos

∀uv ∈ A, u ∈ V ∨ v ∈ V

i.e., para todo arco del grafo, por lo menos uno de sus vértices adyacentes pertenece
a S.
Un clique K en un grafo G es un subgrafo K de G completo. El número de vértices
en el clique mas grande en un grafo G es llamado el número clique del grafo, ω(G)

Hay muchos problemas importantes y difíciles relacionados con las anteriores defini-
ciones. Veamos algunos de ellos.

El problema de la partición independiente

Considere el siguiente problema: se quiere dividir un conjunto de estudiantes en


grupos con la condicion de que ningún par de estudiantes en cada grupo sean amigos
y tal que el número de grupos formados sea mínimo. La relación de amistad es una
relación simétrica. La figura 1.28 muestra un ejemplo simple del problema.

Figura 1.28

Una forma inmediata de resolver el problema consiste en ir seleccionando los estu-


diantes en orden alfabético e irlos asignando al primer grupo en el que no tengan
amigos. El grupo inicial estaría formado por el estudiante A, S1 = {A}.
B no puede estar en S1 por ser amigo de A. Debe formarse un segundo grupo
S2 = {B}
C es amigo de A pero no de B de modo que se puede agregar al grupo S2 y así
S2 = {B, C}. Continuando de esta forma se llega a:

S1 = {A, D, F, I} S2 = {B, C, E, G} S3 = {H}

Planteado en términos generales elproblema de la partición independiente consiste


en, dado un grafo G = (V, A), encontrar una partición {Si } del conjunto de vér-
tices V tal que todos los conjuntos Si sean independientes y que la cardinalidad
de la partición sea mínima. El método usado en el ejemplo anterior se generaliza

51
Grafos

directamente en un algoritmo llamado piVoraz y su seudogódigo, con los vértices


numerados v1 , . . . , vn , es:

S=∅
Para i = 1 hasta |V | haga
Para j = 1 hasta |S| haga
Si Sj ∪ {vi } es independiente
Sj ← Sj ∪ {vi }, salir
Si no j ← j + 1
Si j > |S| entonces
Sj ← {vi }
S ← S ∪ Sj

En cada iteración a cada vértice vi se le asigna un grupo de modo que se requieren


n iteraciones. Y en la i−esima iteración hay que encontrar un grupo para vi . En
el peor de los casos, el grafo completo Kn , vi es adyacente con todos los vértices
ya clasificados y eso requiere 1 + 2 + · + (n − 1) verificaciones, de modo que la
complejidad del algoritmo es O(n2 ).
Pero la pregunta importante es: ¿la solución que este algoritmo construye es óptima?
Desafortunadamente es fácil construir ejemplos para los que el algoritmo puede
retornar muy malas soluciones como en el ejemplo en la figura 1.29

Figura 1.29

52
Grafos

Este ejemplo es un caso particular de un grafo que se puede definir de la siguiente


forma: el conjunto de vértices tiene un número par n de elementos y está dividido
en dos subconjuntos:
V1 = {v1 , v3 , . . . , vn−1 } V2 = {v2 , v4 , . . . , vn }

Los arcos son todos los pares vi vj con vi ∈ V1 y vj ∈ V2 , excepto los casos en que
j = i+1. Para estos grafos el algoritmo retorna n/2 conjuntos como solución cuando
el caso óptimo son solamente dos conjuntos.

Pero una propiedad interesante del algoritmo piVoraz es que, si se tiene alguna
partición que tenga la propiedad dada, pero que no necesariamente sea minimal, los
vértices del grafo se pueden permutar de modo que al aplicar el algoritmo se pueda
obtener una solución posiblemente mejor, como lo expresa el siguiente teorema 14

Teorema 6 Sea S una partición de V en conjuntos independientes. Si se


considera cada clase Si a la vez y se aplica el algoritmo piVoraz con los vértices en
ese orden, también se obtendrá una partición independiente S 0 con |S 0 | ≤ |S|

El problema del cubrimiento por vértices

Dado un grafo G = (V, A), encontrar un cubrimiento por vértices S que minimice
|S|.
El siguiente es un algoritmo voraz de aproximación para este problema:

vcVoraz( G=(V, A))

C:= ∅
mientras A 6= ∅ haga
seleccione cualquier arco uv ∈ A
C:= C ∪{u, v}
remueva todos los arcos incidentes con u o con v de A
retorne C

El algoritmo es correcto pues solo se remueven arcos que ya están cubiertos. Pero
no necesariamente retorna la solución óptima. Lo que puede verse es que retorna
una 2-aproximación a la solución del problema, pues si S es el conjunto formado
por todos los arcos seleccionados por el algoritmo, entonces |C| = 2|S|. Y como

14 R.M.R. Lewis. A Guide to Graph Colouring. Algorithms and Applications. Springer International
Publishing Switzerland 2016. p31

53
Grafos

todo cubrimiento debe tener por lo menos un vértice de cada arco de S, entonces
opt ≥ |S|. por lo tanto 2opt ≥ 2|S| = |C|.

Muchos de los conceptos definidos están fuertemente relacionados. Por ejemplo, es


fácil probar que en un grafo un conjunto de vértices S es un cubrimiento por vértices
si y solo si V − S es un conjunto independiente. Esto es de especial relevancia para
la teoría de la complejidad computacional. El teorema de Cook [1971] probó la
existencia de un primer problema NP-completo, el problema de la satisfabilidad.
Si, como anotan Garey y Johnson 15, todas las demostraciones de NP-completitud
fueran como la del teorema de Cook seguramente esta sería una teoría bastante
esotérica. Pero como ellos mismos recalcan, la teoría creció muy rápido debido a
que una prueba de NP-completitud ahora se hace en cuatro pasos. Para probar que
un problema Π es NP-completo:

i. Se muestra que Π está en NP.

ii. Se selecciona un problema Π‘ conocido como NP-completo.

iii. Se construye una transformación f de Π Π0 .

iv. Se prueba que f es una transformación polinomial.

Tres de los seis problemas NP-completos básicos que proponen son de la teoría de
grafos, dos de ellos tratados en esta sección, el otro más adelante.

• Cubrimiento por vértices


Dado un grafo G=(V, A) y un entero k ≤ |V |, ¿ tiene G un cubrimiento por
vértices de tamaño k?

• Clique
Dado un grafo G=(V, A) y un entero k ≤ |V |, ¿ tiene G un clique de tamaño k
o mayor?

El siguiente teorema muestra como un problema se puede transformar en otro.

Teorema 7 G tiene un clique de tamaño k si y solo si Ḡ tiene un cubrimiento


por vértices de tamaño |V | − k

Demostración
Sea Ḡ = (V, Ā) el grafo complemento de G.

15 Michael R. Garey, David S. Johnson. Computers And Intractability. A Guide to the Theory of
NP-Completeness. W. H. Freeman and Company

54
Grafos

Supongamos que G tiene un clique K ⊆ V, |K| = k. Sea uv ∈ Ā un arco en el


complemento de G. Entonces uv ∈ / A. Así, o u ∈
/K ov∈
/ K (pues K es completo).
Entonces uv está cubierto por un vértice en V − K.

Ahora supongamos que Ḡ tiene un cubrimiento por vértices s ⊆ V, |S| = |V | − k.


Para todo par u, v ∈ V , si uv ∈ Ā, entonces u ∈ S o v ∈ S (o ambos). Así, para
todo par u, v ∈ V , si u, v ∈
/ S entonces uv ∈
/ Ā y por lo tanto uv ∈ A; i.e., para todo
par u, v ∈ V − S, uv ∈ A. K = V − S es un clique en G y |K| = k .

1.14 Emparejamientos

Un emparejamiento 16 en un grafo G es un subconjunto M de vértices independientes,


i.e., ningún par de arcos del conjunto tienen vértice en común. Los vértices de un
emparejamiento son llamados M −saturados o simplemente saturados. Si cada v ∈ V
aparece exactamente una vez en M se dice que el emparejamiento es perfecto.
Un emparejamiento M en un grafo G es llamado maximum si no existe otro empare-
jamiento M 0 en el grafo tal que |M 0 | > |M |.
Un emparejamiento M en un grafo G es llamado maximal si no existe otro empare-
jamiento M 0 en el grafo que contenga estrictamente a M.
Un problema con muchas aplicaciones en teoría de grafos es encontrar emparejamien-
tos maximum en un grafo.
Sea M un emparejamiento cualquiera en G. Una trayectoria en G que inicie en
un vértice no saturado y que alternadamente contenga arcos de A − M y de M es
llamada una trayectoria alternante con respecto a M . Y es llamada una trayectoria
alternante de aumento si la trayectoria alternante termina en un vértice que tampoco
está saturado. Las trayectorias alternantes de aumento son importantes porque
permiten transformar un emparejamiento M en otro de mayor tamaño. En efecto,
como se ve en la figura 1.30, Dado un emparejamiento M y una trayectoria de
aumento T , la diferencia simétrica, M 4 T es otro emparejamiento que tiene un
arco más.

Teorema 8 Un emparejamiento M en un grafo G es maximum si y solo si G


no tiene trayectorias alternantes de aumento.

Dem. Si M es maximum no puede haber trayectorias de aumento pues si hubiera


una trayectoria de aumento T es fácil ver que M 4 T es otro emparejamiento que
tiene un arco más.

16 Matching en inglés

55
Grafos

Figura 1.30 Una trayectoria de aumento.

Si M no es maximum, existe un emparejamiento M 0 con . Las componentes del


subgrafo G[M 4 M 0 ] deben ser trayectorias o ciclos en las que los arcos alternan
entre M y M 0 . Pero como |M 0 | > |M |, debe existir una trayectoria que inicie y
termine en un arco de M 0 y esta es una trayectoria alternante de aumento para M.
6-10-14-13-12-11 en la figura 1.31.

Figura 1.31

56
Grafos

1.15 Grafos bipartitos

Un grafo G = (V, A) es bipartito si existen dos subconjuntos disyuntos X, Y de V


tales que:
i. X ∪ Y = V
ii. Para cada uv ∈ A, u ∈ X, v ∈ Y o v ∈ X, u ∈ Y
Usualmente los grafos bipartitos se denotan con G = (X, Y, A)
En general, un grafo G = (V, A) se llama r−partito si V admite una partición en r
clases tal que todo a ∈ A tiene sus extremos en clases diferentes.
Proposición 16 Un grafo es bipartito si y solo si no tiene ciclos impares
Dem. ⇒) Si un grafo es bipartito, todo subgrafo lo es, y un ciclo impar no puede
ser bipartito.
⇐) Supongamos que G es conexo. Sea T un árbol de cubrimiento en G con una
raíz escogida r ∈ T . Se puede definir un orden parcial entre los vértices del grafo
así:
u < v si la única trayectoria en el árbol que va de r a v pasa por u.
Para cada v ∈ V , la única trayectoria rT v en el árbol T es par o impar. Sean:
X = {v| rTv es par}
Y = {v| rTv es impar}
Esto define una bipartición en el grafo. Claramente V = X ∪ Y .
Sea uv ∈ A un arco cualquiera de G. Hay dos posibilidades:
1. uv ∈ T . Supongamos u < v. Entonces rT v = rT uv y u y v están en clases
distintas.
2. uv ∈
/ T . En el árbol T hay una trayectoria uT v y uT v ∪ uv forman un ciclo. Pero
como el grafo no tiene ciclos impares, los vértices del ciclo se deben alternar y
por lo tanto u y v están en clases distintas.
Un algoritmo para encontrar trayectorias de aumento en grafos bipartitos

Trayectoria-de-Aumento (G, M ). G = (X, Y, A)

Dirigir arcos: X → Y si e ∈/ M ; Y → X si e ∈ M .
Agregar s, t y conectarlos con los vértices libres en X y Y.
Correr BFS y retornar la ruta más corta, P , de s a t.
retorna P − {s, t}

57
Grafos

Match-Bipartito (G)
M =∅
Repetir:
P = Trayectoria-de-Aumento (G, M )
M =M 4P
hasta que P = ∅

Figura 1.32 El algoritmo Trayectoria-de-Aumento.

Teorema 9 [König] La máxima cardinalidad de un emparejamiento en un


grafo G es igual a la mínima cardinalidad de un cubrimiento por vértices.

Dem. Sea M un emparejamiento en G de cardinalidad máxima. De cada arco en M


se escoge uno de sus extremos así: su extremo en Y si alguna trayectoria alternante
finaliza en ese vértice; el extremo en X en otro caso. Sea U el conjunto formado por
los vértices así escogidos.
Veamos que U es un cubrimiento por vértices del grafo. Sea ab un arco cualquiera
del grafo. Hay dos posibilidades:

1. ab ∈ M . Por la construcción del conjunto U , o a está en U o b está en U .

2. ab ∈/ M . Hay un arco a0 b0 ∈ M tal que a = a0 o b = b0 , pues si no fuera así M


no sería maximal. Si b = b0 , hay una trayectoria alternante (ab0 ) que finaliza en
b0 = b y por lo tanto b ∈ U . Finalmente si a = a0 hay también dos posibilidades:
si a0 ∈ U entonces a ∈ U . Y si b0 ∈ U hay una trayectoria alternante xT b0 que

58
Grafos

termina en b0 . Pero entonces xT b0 ab es una trayectoria alternante que termina en


b y b ∈ M (pues si no fuera así se tendría una trayectoria de aumento) y b ∈ U .

Como todo cubrimiento por vértices de G debe cubrir a M , no pueden haber cubrim-
ientos con menos de |M | vértices.

La demostración del anterior teorema es constructiva pues dado un grafo permite en-
contrar un cubrimiento. Para el ejemplo de la figura 1.33, si se sigue la demostración
se encuentra que U = {2, 5, 8, 11}.

Figura 1.33 Un ejemplo para el teorema de König.

En un grafo bipartito G = (X, Y, A), para todo v ∈ X y para todo subconjunto S


de X se definen los conjuntos
[
N (v) = {w ∈ Y | vw ∈ A} N (S) = N (v)
v∈S

Y para un emparejamiento M , al vértice Srelacionado con v se le denota con M (v) y


para todo subconjunto S de X; M (S) = s∈S M (s). Se dice que el emparejamiento
cubre X si todos los vértices de X están en M .

Un grafo bipartito G = (X, Y, A) cumple la condición de Hall si |S| ≤ |N (S)| para


todo S ⊆ X

Teorema 10 En un grafo bipartito G = (X, Y, A) en el que cada vértice en X


está unido con por lo menos un vértice en Y existe un emparejamiento que cubre X
si y solo si se cumple la condición de Hall.

Dem.
⇒ Sea S cualquier subconjunto de X. Si hay un emparejamiento que cubre X,
M (S) ⊆ N (S) y entonces |S| = |M (S)| ≤ |N (S)| para todo S ⊆ U .
⇐ Por inducción fuerte
Si |X| = 1 el resultado es inmediato.

59
Grafos

Si |X| > 1 hay dos posibilidades:

a. |S| < |N (S)| para todo S ⊆ X. Escoja cualquier elemento u ∈ X y algún


arco uw. Si se eliminan el arco y sus vértices del grafo, se sigue cumpliendo la
condición de Hall y, por hipótesis de inducción hay existe un emparejamiento
que cubre X − v. Se agrega uw a este emparejamiento.

b. Para algún S ⊆ X, |S| = |N (S)|. Por hipótesis de inducción se puede hacer un


emparejamiento M que cubre S. Se eliminan los arcos de ese emparejamiento
del grafo. La condición de Hall se mantiene pues si S 0 = X − S y Y 0 = Y − M (S)
entonces:
|S ∪ S 0 | ≤ |M (S) ∪ Y 0 | por la condición de Hall
|S| + |S 0 | ≤ |M (S)| + |W 0 | por ser conjuntos disyuntos. Como |S| = |M (S)| en-
tonces |S 0 | ≤ |W 0 | y se mantiene la condición de Hall. Nuevamente por hipótesis
de inducción, se puede hacer un emparejamiento M 0 que cubre S 0 y el empare-
jamiento que cubre X es M ∪ M 0 .

El problema del matrimonio estable

Sea G = (X, Y, A) un grafo bipartito con |X| = |Y |. Supongamos además que


para cada u ∈ X, N (u) está ordenado por algún orden de preferencia. La notación
x u y indica que entre x y y, u prefiere a x.
En un emparejamiento M, dos vértices x ∈ U, y ∈ W forman un par bloqueador si:

i. M (x) 6= y

ii. y x M (x)

iii. x y M (y)

El emparejamiento es estable si no tiene pares bloqueadores.

Teorema 11 Para el grafo Kn,n existen emparejamientos perfectos y estables


para cualquier lista de preferencias.

Dada cualquier lista de preferencias, el siguiente algoritmo encuentra un empare-


jamiento perfecto y estable

El algoritmo de Gale-Shapley

Sean M0 = ∅, y P (x) = ∅ para todo x ∈ X


Se repite el siguiente proceso hasta que todos los vértices estén en el emparejamiento:
Se escoge un vértice x ∈ X que no esté emparejado en Mi−1 y sea y ∈ Y el vértice
más preferido por x que no está en P (x)

60
Grafos

1. Agregar y a P (x).

2. Si y no está emparejada, hacer Mi = Mi−1 ∪ {xy}

3. Si zy ∈ Mi−1 y x y z, entonces Mi = (Mi−1 − zy) ∪ {xy}

La versión feminista del algoritmo (que usualmente produce resultados diferentes)


resulta al intercambiar las x con las y.

La figura 25 presenta un ejempo elemental para aplicar el algoritmo de Gale-Shapley.


El conjunto de hombres es {A, B, C, D} y el de mujeres {a, b, c, d}, cada uno
tiene su lista de preferencia.

Figura 1.34 Un ejemplo para


el algoritmo de Gale-Shapley.

En la figura 26 se ven los resultados intermedios y final al aplicar el algoritmo.

Figura 1.35 Resultados parciales y finales


aplicando el algoritmo de Gale-Shapley.

61
Grafos

1.16 Grafos Eulerianos y Hamiltonianos

Una trayectoria de Euler en un grafo G es una trayectoria que incluye cada arco del
grafo. Un tour de Euler es una trayectoria de Euler cerrada. Un grafo conexo G es
Euleriano si tiene un tour de Euler.

Teorema 12 Si G es un grafo conexo, las siguientes proposiciones son equiv-


alentes:

i. G es Euleriano.

ii. El grado de cada vértice de G es par.

iii. G es unión arco-disyunta de ciclos.

Dem. i) ⇒ ii): Sea T un tour de Euler que inicia en algún vértice v0 ∈ V . Sea v
cualquier vértice diferente de v0 . Cada vez que T llega a v por algún arco, debe salir
por un arco diferente para regresar a v0 , i.e., cada visita del tour a v usa dos arcos.
Como el tour debe recorrer todos los arcos, d(v) debe ser par. Para v0 , cada vez que
T sale, debe regresar. Por lo tanto d(v0 ) también debe ser par.

ii) ⇒ iii): Como δ(G) ≥ 2, G debe tener un ciclo C1 . Si no tuviera ciclos sería
un árbol y los árboles deben tener hojas. Si se eliminan los arcos de este ciclo, el
grado de cada vértice en el ciclo se reduce en dos y sigue siendo par. Si quedan
vértices aislados se pueden remover. Sea G1 el grafo resultante. Si G1 no es vacío se
puede repetir el mismo argumento para llegar a un grafo G2 y continuar asi hasta
llegar a Cn = ∅. El grafo G debe ser entonces la unión arco-disyunta de los ciclos
C1 , . . . , Cn−1 .

iii) ⇒ i): G es la unión arco-disyunta de los ciclos C1 , . . . , Cn−1 . Para C1 , debe


existir algún Ci , i 6= 1 con por lo menos un vértice en común v, pues si no fuera
así el grafo no sería conexo. Los ciclos C1 y Ci se pueden combinar para formar un
solo subgrafo con tour de Euler como se indica en la figura 1.36. Se inicia el paseo
de Euler por G1 pero al llegar al vértice común v se continua el paseo de Euler por
G2 hasta volver a ese vértice retomando entonces el paseo por G1 . El argumento se
puede repetir: debe existir algún Cj , j 6= 1, i con por lo menos un vértice en común
con C1 ∪ Ci etc. Se continua el procedimiento hasta tener un único paseo de Euler
por el grafo completo.

62
Grafos

Figura 1.36 Combinando ciclos de Euler.


La demostración de la proposición anterior es la base para el siguiente algoritmo:

Algoritmo de Hierholzer. [1873]

Sea C0 un ciclo cualquiera en G.


Mientras haya arcos de G que no están en Ci :
Escoja cualquier vértice w en Ci incidente con un arco que no este en
Ci .
Empezando en w construya un ciclo D con arcos que no esten en Ci .
Combine Ci con D para obtener Ci+1

El siguiente algoritmo que también construye un ciclo de Euler se basa en el principio:


los puentes son los últimos arcos que debemos cruzar.

Algoritmo de Fleury [1883]

• Sea v un vértice cualquiera en G y C = {v}

• Mientras G − E(C) contenga arcos incidentes con v

i. Escoja un arco e = vw ∈ G − E(C) que no sea puente, a menos que no


haya otra alternativa.

ii. Agrege e a C y haga v := w

63
Grafos

La corrección del algoritmo se basa en dos observaciones. Durante la ejecución del


algoritmo hay a lo más un puente incidente con v, y ese arco será el último en usarse
permitiendo cruzar todos los arcos incidentes con todos los vértices en G. Y esto es
así, pues si se quedara atrapado en algún vértice v antes de que todos los arcos se
cruzen esto implicaría o que v tiene grado impar o que el grafo no era conexo, pero
ninguna de estas dos cosas pueden suceder.

Si el grafo tiene exactamente dos vértices de grado impar existen trayectorias Eule-
rianas que empiezan en uno de esos vértices y terminan en el otro. Los anteriores
algoritmos se pueden adaptar de inmediato para encontrar esas trayectorias. sim-
plemente se agrega un arco más que conecte los dos vértices impares, se corre el
algoritmo y después de tener el ciclo Euleriano se elimina el arco que se agregó.

El problema del cartero chino [H. E. Dudeney(1917), Mei-ko Kwan(1962)]

Se tiene un grafo G con pesos positivos y se busca un paseo que recorra todos los
arcos del grafo, partiendo de un vértice determinado y volviendo a él, y que tenga
peso total mínimo.

Si el grafo es euleriano, obviamente cualquier tour de Euler es óptimo. El problema


es si el grafo no es euleriano pues entonces el paseo tendrá que pasar por algunos
arcos más de una vez.
El siguiente algoritmo da una solución para este problema.

Sea V0 el conjunto formado por los vértices de grado impar en G.

a. Para cada par de vértices x, y ∈ V0


Encontrar la trayectoria más corta xT y en G.

b. Construir un grafo completo K con el conjunto de vértices V0 en el que cada


arco tiene como peso el peso total de la trayectoria más corta xT y.

c. Encontrar un emparejamiento perfecto M de peso mínimo en K

d. Para cada arco a ∈ M :


Duplicar los arcos en G de la trayectoria más corta correspondiente a
a.

e. Sea G0 el multigrafo resultante. Encontrar un paseo de Euler en G0 .

64
Grafos

Encontrar trayectorias de costo mínimo se puede hacer rápidamente usando Dijkstra.


El problema de encontrar un emparejamiento perfecto de peso mínimo se puede hacer
en tiempo polinomial y ya vimos dos algoritmos para encontrar paseos de Euler.
La figura 1.37 es un ejemplo sencillo del problema del cartero chino. En las figuras
1.38 y 1.39 se ven los resultados al aplicar el anterior algoritmo.

Figura 1.37 Un ejemplo del problema del cartero chino.

Figura 1.38 K4 y el emparejamiento perfecto.

Otro problema muy similar al de los ciclos de Euler, pero que curiosamente en el
mundo de la complejidad computacional está en sus antípodas es el problema de los
ciclos Hamiltonianos. Un ciclo Hamiltoniano en un grafo es un ciclo que pasa por
todos los vértices del grafo. Los autores de [4] escriben: ‘’Si bien los grafos Eulerianos
admiten una caracterización elegante, aún no se conoce una caracterización decente
de los grafos Hamiltonianos. De hecho, es uno de los problemas no resueltos más
difíciles en teoría de grafos; es un problema NP-completo. Se conocen muchas

65
Grafos

Figura 1.39 Las líneas dobles indican


los arcos que se recorren dos veces.

condiciones suficientes para que un grafo sea Hamiltoniano; sin embargo ninguna de
ellas resulta ser una condición necesaria elegante.
El siguiente es un ejemplo de una de esas condiciones. ω(H) es el número de com-
ponentes del grafo H.

Teorema 13 Si G es Hamiltoniano, entonces para todo subconjunto propio S


de V, ω(G − S) ≤ |S|

Dem. Sea C un ciclo de Hamilton en el grafo G. Es claro que ω(G − S) ≤ ω(C − S).
Si se remueve un vértice v del grafo, C − v es una trayectoria y ω(C − v) = 1. Y
al remover cualquier vértice de una trayectoria, o el número de componentes de la
trayectoria queda igual (si es un vértice extremo), o aumenta en 1, de modo que
ω(C − S) nunca podrá ser mayor que |S|.

En el grafo a) de la figura 1.40 se ve que para el conjunto S de vértices marcados


ω(G − S) = 3 > 2 = |S| y como no cumple la condición del teorema, no es Hamil-
toniano. El grafo de la b) de la misma figura , llamado grafo de Petersen, cumple
con la condición pero tampoco es Hamiltoniano. Eso muestra que la condición del
teorema no es suficiente.

Un cálculo combinatorio puede ser un indicio de la complejidad de los problemas con


ciclos hamiltonianos. Es fácil ver que para el grafo completo Kn existen (n − 1)!/2
ciclos Hamiltonianos. Este número crece demasiado rápido. En K24 (que es un grafo
muy pequeño) hay del orden de 1023 ciclos Hamiltonianos. Un computador que liste
medio millón de ciclos por segundo demoraría millones de años evaluandolos todos!

66
Grafos

Figura 1.40 Dos grafos no Hamiltonianos.

1.17 Coloreando grafos

Un grafo se llama k−coloreable si a cada uno de sus vértices se le puede asignar un


color de modo que vértices que sean adyacentes tengan colores distintos y el número
de colores distintos es k. χ(G), el número cromático de G, es el mínimo entero tal
que G es k−coloreable.
Para k = 2, el problema de saber si G es k−coloreable es equivalente al problema de
saber si G es bipartito y hay algoritmos polinomiales para resolver este problema.
Pero el problema es NP-completo para todo valor fijo de k ≥ 3; solo se conocen
algoritmos polinomiales para algunos grafos especiales.

Teorema 14 Un grafo con grado máximo k, es k + 1 coloreable

Demostración: Por inducción sobre n, el número de vértices.


Caso base: n = 1 el grado máximo es 0 y el grafo es 1−coloreable.
Paso inductivo: Supongamos el teorema cierto para todo grafo con n vértices y sea G
un grafo con n+1 vértices y con grado máximo k. Si se elimina un vértice cualquiera
v se obtiene un grafo con n vértices y con grado máximo k. Por hipótesis de inducción
este grafo es k + 1−coloreable. Al agregar nuevamente el vértice eliminado v, a este
vértice se le puede asignar un color diferente al de todos sus vecinos pues estos son
a lo más k y se tienen k + 1 colores.

Un resultado interesante es que, con dos condiciones adicionales, el número de colores


puede reducirse en 1.

Teorema 15 (Brooks) 17 Todo grafo conexo G con grado máximo ∆ se puede


∆-colorear, a menos que G sea isomorfo a K∆+1 o a un ciclo de longitud impar
para el caso ∆ = 2.

67
Grafos

El siguiente es un algoritmo muy intuitivo, llamado de coloreado secuencial para


colorear un grafo. Se supone que los vértices del grafo están numerados {v1 , . . . , vn }
y que los posibles colores a usar son simplemente {1, . . . , n}. ci es el color asignado
al vértice vi .

1. Para i = 1, . . . , n Li = [1, . . . , i].

2. Para i = 1, . . . , n
Sea ci el primer elemento de Li
Para cada j, i < j y xi xj ∈ A, Lj := Lj − ci

Aplicando el anterior algoritmo al grafo de la figura 1.41:

Figura 1.41 Coloreando un grafo.

al terminar el algoritmo el resultado se muestra en la tabla 1.6.

El problema con este algoritmo es que el resultado depende no solamente del grafo
sino también de la enumeración de los vértices (se puede repetir el anterior ejemplo
con otra enumeración); y por esto diferentes enumeraciones pueden producir difer-
entes coloreados. Es posible que el algoritmo use una cantidad de colores mucho
más grande que el número cromático del grafo.

17 La demostración se puede consultar en Robert A. Wilson. Graphs, Colourings and the Four-Colour
Theorem. Oxford University Press

68
Grafos

i Li ci
1 (1) 1
2 (2) 2
3 (1, 3) 1
4 ( 2, 3, 4) 2
5 (1, 3, 4, 5) 1
6 (2, 3, 4, 5, 6) 2
7 (3, 4, 5, 6, 7) 3

Tabla 1.6 Resultado


del algoritmo CS.

También se puede plantear el problema del coloreado de arcos, que consiste en asignar
a cada arco de un grafo un color de forma que arcos que tengan un vértice en común
tengan distintos colores. Se define el número arco-cromático de G, χ´(G), como
el menor número de colores necesarios para arco-colorear el grafo G. Un resultado
interesante para este problema es que el equivalente del teorema de Brooks muestra
que para cualquier grafo G, χ´(G) solamente puede ser uno de dos posibles valores.

Teorema 16 (Vizing) Para todo grafo G se tiene que. o χ´(G) = ∆(G) o


χ´(G) = ∆(G) + 1.

La demostración del teorema de Vizing se puede consultar en [1]

1.18 El teorema de la galería de arte

En 1973 Victor Klee propuso el siguiente problema: Suponga que el director de un


museo quiere estar seguro de que en todo momento cada punto de un museo esté
vigilado por un guarda. Los guardas se ubican en puntos fijos, pero pueden girar
sin problemas. ¿Cuantos guardas se necesitan?
Obviamente, si toda la planta del museo forma un polígono convexo, un solo guarda
es suficiente. El caso interesante es si este no es el caso. Se tiene el siguiente
resultado:

Teorema 17 Para cualquier museo con n paredes, b n3 c guardas son suficientes

Para probar este resultado se prueba primero lo siguiente:

Todo polígono planar no convexo se puede triangular

69
Grafos

Figura 1.42 Una galería de arte.

Demostración por inducción en el número de vértices


Si n = 3 el polígono ya es un triángulo.
Sea n ≥ 4. Un vértice v de un polígono P se llama convexo si el ángulo interior es
menor a π. Como la suma de los ángulos interiores de P es (n − 2)π, tiene que haber
por lo menos tres vértices convexos (aplicando el principio del palomar). Sea v uno
de ellos. Sean u, w los dos vértices vecinos de v. Si la diagonal uw está dentro de
P, se escoge esta diagonal. Si no es porque en el triángulo vuw hay otros vértices
de P. Se puede entonces ir moviendo la diagonal uw hacia v hasta que encuentre el
último vértice z dentro del triángulo. Se escoge entonces la diagonal vz.
En cualquiera de los dos casos la diagonal escogida divide a P en dos polígonos
con menor número de vértices. Por indución fuerte estos polígonos se pueden tri-
angular con diagonales que no se cruzan. La unión de esas triangulaciones es una
triangulación de P.
Y ahora se prueba el siguiente resultado:

Toda triangulación es 3−coloreable

Evidente si n = 3.
Si n > 3, se escogen dos vértices u, v unidos por una diagonal. Primero se asigna
el color 1 a u y el color 2 a v. Esta diagonal separa al grafo en dos subgrafos
triangulados que, por inducción son 3−coloreables y la unión de esos coloreados es
una coloración para el grafo. completo.

Finalmente, todo triángulo tiene un vértice de color 1 y hay a lo más b n3 c con este
color. Esos son los puntos en los que se ubican los guardas y todo el museo queda
vigilado.

70
Grafos

1.19 Grafos planares

Un grafo planar es un grafo que se puede dibujar en un plano de forma tal que sus
arcos no se intersecten. Las regiones delimitadas por los arcos de un grafo planar
son llamadas sus caras.

Teorema 18 Fórmula de Euler


Sea G = (V, A) un grafo planar conexo, |V | = v, |A| = a y c el número de caras.
Entonces:
v−a+c=2

Este teorema se puede demostrar de diversas formas. Veamos dos de ellas.


Dem1. Se escoge cualquier arco del grafo y se va contrayendo hasta que los dos
vértices en sus extremos se unan. Al hacer este procedimiento pueden suceder dos
cosas:

• Se reduce el número de arcos en uno y el número de vértices en uno y no cambia


el número de caras de modo que el número v − a + c no cambia.

• Pueden aparecer arcos paralelos y la región entre ellos sería una cara. Si esto
sucede se pueden unir los dos arcos paralelos en uno solo de modo que se reduce
la cantidad de arcos en dos, el número de caras en uno y el número de vértices
en uno y entonces el número v − a + c tampoco cambia.

Si se continua con este proceso de remover arcos finalmente se llega a un único


vértice y entonces v = 1, a = 0, c = 1 y v − a + c = 2. Como v − a + c nunca cambia
en el proceso (se le llama un invariante), v − a + c = 2 también para el grafo inicial.

La anterior demostración puede parecer muy poco formal. La siguiente es una


demostración más rigurosa.
Dem2. Demostración por inducción en el número de arcos
Caso base Si a = 0, entonces v = 1, c = 1.
Paso inductivo Consideremos un grafo con a + 1 arcos. Hay dos casos:

i. G no tiene ciclos. Entonces G es un árbol y hay a + 2 vértices y una cara

v − a + c = (a + 2) − (a + 1) + 1 = 2

ii. G tiene por lo menos un ciclo. Seleccione un árbol span y un arco uv que esté en
el ciclo pero no en el árbol. Si se elimina ese arco, el número de caras se reduce

71
Grafos

en 1 y se obtiene un grafo planar G0 conexo con a arcos y el mismo número de


vérticesy c caras. Por hipótesis de inducción en este grafo v − a + c = 2 y así:
v − (a + 1) + (c + 1) = v − a + c = 2

Proposición 17 El grafo K5 no es planar.

Dem. Supongamos que el grafo K5 fuera planar. Como en ese grafo v = 5, a = 10,
por la fórmula de Euler el número de caras debe ser 7. Ahora, como cada arco limita
dos caras se tiene que 2a = pc donde p es el número promedio de lados en todas las
caras del grafo. Pero p ≥ 3 y por lo tanto 2a ≥ 3c. Reemplazando los valores de a
y c se concluye que 20 ≥ 21; imposible.

Proposición 18 El grafo K3,3 no es planar.

Dem. K3,3 es un grafo bipartito y por lo tanto no tiene ciclos impares. Entonces
toda cara debe tener por lo menos 4 arcos de borde. Sea S la suma de todos los
arcos borde de todas las caras de K3,3 . Entonces S ≥ 4c.
Pero al sumar todos los arcos borde, cada arco se cuenta 2 veces y por lo tanto
S ≤ 2a. Así:
a 9
4c ≤ 2a i.e. c ≤ =
2 2
Por la fórmula de Euler:
c=a−v+2=9−6+2=5

y entonces 5 ≤ 92 . Absurdo.

Uno de los resultados más famosos en teoría de grafos, debida a Kazimiers Kura-
tovski, es una caracterización de los grafos no planares que básicamente establece
que los culpables de la no planaridad de un grafo son esencialmente K3,3 y K5 . Para
entender el teorema es necesaria la siguiente definición. Una subdivisión de un grafo
G es un grafo H que se puede obtener de G mediante la operación de insertar un
número arbitrario de vértices nuevos en cualquier arco. G se considera una sub-
división de sí mismo. Dos grafos H y H’ son llamados homeomorfos si ambos son
isomorfos a subdivisiones del mismo grafo G.

Teorema 19 (Kuratovski) Un grafo es planar si y solo si no contiene ningún


subgrafo homeomorfo a K3,3 o K5 .

En algoritmos anteriores se usó otra operación en grafos que consistía en la contrac-


ción de arcos. El siguiente teorema proporciona otra caracterización interesante de
los grafos planares.

72
Grafos

Teorema 20 (Wagner) Un grafo es planar si y solo si no contiene ningún


subgrafo contraible a K3,3 o K5 .

Para los grafos planares también hay resultados importantes respecto al problema
del coloreado.

Proposición 19 En todo grafo planar a ≤ 3v − 6

Dem. En la demostración de la proposición anterior se concluyo que en todo grafo


planar 3c ≤ 2a. Usando la fórmula de Euler:
6 = 3v − 3a + 3c ≤ 3v − 3a + 2a = 3v − a

Proposición 20 Todo grafo planar tiene un vértice de grado a lo más 5

Dem. Supongamos que existe un grafo planar en el que d(v) ≥ 6 para todo vértice
v. Entonces:
X
6v ≤ d(v) = 2a ⇒ a ≥ 3v
v∈V

lo que contradice la proposición anterior.

Teorema 21 Todo grafo planar es 5−coloreable

Demostración por inducción en el número de vértices


Caso base. Para |V | ≤ 5 el resultado es inmediato.
Paso inductivo. Supongamos |V | > 5. Por la proposición anterior, se puede elegir
en el grafo un vértice v con grado menor o igual a 5. Hay dos posibilidades:

1. d(v) < 5. El grafo G − v es planar y por hipótesis de inducción es 5-coloreable.


Al agregar nuevamente el vértice v, como este vértice tiene menos de 5 vecinos
se puede colorear con uno de los colores no usados por sus vecinos.

2. d(v) = 5. Los 5 vecinos del vértice v no pueden ser todos adyacentes entre
sí, pues si lo fueran el grafo contendría a K5 y no sería planar. Se escogen
dos vecinos de v, n1 y n2 , no adyacentes. Estos dos vecinos se pueden unir en
un único vértice para tener un nuevo grafo con un vértice menos ( no importa
si aparecen arcos paralelos , se pueden considerar uno solo). Nuevamente por
hipótesis de inducción este nuevo grafo es 5-coloreable. Al volver a separar a n1 y
n2 y regresar al grafo inicial se tiene un grafo 5-coloreado en el que n1 y n2 tienen
el mismo color pero no hay problema porque estos vértices no son adyacentes.

73
Grafos

[1] Dieter Jungnickel. Graphs, Networks and Algorithms. Fourth Edition. Algo-
rithms and Computation in Mathematics - Volume 5. Springer, 2013.

[2] Gross Jonathan, Yellen Jay, Zhang Ping, eds. Handbook of Graph Theory.
Second edition. Discrete Mathematics and its Applications. CRC Press.

[3] J. A. Bondy, U. S. R. Murty. Graph Theory Whit Applications. North-Holland.

[4] R. Balakrishnan. K. Ranganathan. A Textbook of Graph Theory. Second


Edition. Springer Science+Business Media New York 2012

[5] J. Matousek, J. Nesetril. Invitation to Discrete Mathematics. 2nd edition. Ox-


ford University Press.

[6] Santanu Saha Ray. Graph Theory with Algorithms and its Applications. Springer
India 2013.

[7] Shimon Even. Graph Algorithms. Cambridge University Press.

[8] Higgins Peter M. Nets, Puzzles, and Postmen. Oxford University Press. 2007

[9] Lovász L. et al. Discrete Mathematics, Elementary And Beyond. Springer 2003.

[10] Dr. Herbert Fleischner. Algorithms in Graph Theory. TU Wien, Database and
Artificial Intelligence Group.

[11] Reinhard Diestel. Graph Theory. Springer - Verlag. Nueva York, 2000.

[12] Richard J. Trudeau. Dots and Lines. The Kent State University Press. 1976.

[13] Tero Harju. Lecture Notes on Graph Theory. Department of Mathematics


University of Turku FIN-20014 Turku, Finland.

74

Potrebbero piacerti anche