Está en la página 1de 72

Universidad de Valladolid

Departamento de informtica
Campus de Segovia

Estructura de datos
Tema 7: Grafos

Prof. Montserrat Serrano Montero

NDICE

Representacin y operaciones
Conceptos bsicos
Representaciones
Operaciones del TAD Grafo
Recorridos

CONCEPTOS BSICOS

Los grafos permiten representar relaciones


arbitrarias entre datos. No es necesario
que exista una jerarqua.

Los grafos se clasifican en:


a) dirigidos
b) no dirigidos

Sus aplicaciones son muy variadas. Se usan


para modelar problemas de diversas
disciplinas (comunicaciones, ingeniera,
biologa, etc.)

En la representacin en grafo cada objeto del


problema forma un nodo. La relacin,
comunicacin o conexin entre nodos da
lugar a una arista, que puede ser
bidireccional (no dirigida) o dirigida.

CONCEPTOS BSICOS

Un grafo es un conjunto de vrtices o nodos V


y un conjunto de arcos A. Se representa con el
par G = {V, A}.

Cuando un nodo v1 apunta a otro nodo v2 se


dice que hay un arco o arista (v1, v2) que va
del vrtice v1 al vrtice v2.

Un grafo se dice que es no dirigido si se


cumple la condicin de que si (v1, v2) es un
arco del grafo, entonces tambin lo es el arco
(v2, v1).

Para representar un grafo grficamente, se


recurre a dibujar un conjunto de crculos que
simbolizan los vrtices y un conjunto de
segmentos entre ellos que representan los
arcos. Si se trata de un arco dirigido los
segmentos sern flechas.

CONCEPTOS BSICOS

Un grafo es un conjunto de vrtices o nodos V


y un conjunto de arcos A. Se representa con el
par G = {V, A}.

G1 = {V1, A1}
G2 = {V2, A2}
G1 es no dirigido. V1 = {1, 4, 5, 7, 9}
A1 = {(1, 4), (5, 1), (7, 9), (7, 5), (4, 9), (4, 1),
(1, 5), (9, 7), (5, 7), (9, 4)}; (v1, v2) v1-v2
G2 es dirigido (digrafo). V2 = {C, D, E, F, H}
A2 = {(C, E), (E, D), (F, E), (F, H), (H, F),
(D, H)}; (v1, v2) v1 v2

CONCEPTOS BSICOS
ADYACENCIA:

En un grafo no dirigido si la arista (v1, v2)


pertenece al conjunto de las aristas del grafo
se dice que los vrtices v1 y v2 son
adyacentes.

En un grafo dirigido si el arco (v1, v2)


pertenece al conjunto de arcos del grafo, se
dice que v1 es adyacente con v2 y v2 es
adyacente desde v1. No implica la situacin
recproca.

Un grafo valorado (etiquetado) es aquel que


lleva asociado un factor de peso a cada arco
o arista. (Ej. peso: los Km. entre ciudades)

CONCEPTOS BSICOS

GRADO DE UN VRTICE:
Nmero de arcos o aristas incidentes a dicho
vrtice.

En un grafo no dirigido, el grado de un nodo


es el nmero de aristas que contienen a ese
nodo.

En un grafo dirigido podemos considerar:


a) Grado de entrada: n de arcos que llegan a
un vrtice.
b) Grado de salida: n de arcos que salen de
un vrtice.
c) Vrtice aislado: si tiene grado de entrada y
salida cero.
d) Vrtice fuente: tiene grado de entrada
cero.
e) Vrtice sumidero: tiene grado de salida
cero.

CONCEPTOS BSICOS

Un camino entre dos vrtices vi, vj es una


sucesin ordenada de vrtices del grafo que
cumplen las condiciones siguientes: el
primer vrtice es vi; el ltimo vrtice es vj;
cualquier par de vrtices consecutivos vp, vq
cumplen la condicin de que (vp, vq) es un
arco del grafo.

La longitud de un camino es el n de arcos


que lo forma. Si el grafo es valorado, se
define la longitud como la suma de los
valores de los arcos que lo forman.

Un camino simple entre dos vrtices vi, vj


es un camino en el que todos los vrtices son
distintos excepto el primero y el ltimo si es
un ciclo.

Un ciclo es un camino simple cerrado,


compuesto al menos por 3 nodos.

Un bucle es un camino de
un vrtice a s mismo, (v, v).

CONCEPTOS BSICOS
Ejemplos:
a)

Qu tipo de camino forman los


vrtices (A, E, B, F, A) de este grafo?,
cul es su longitud?
b) Idem a) pero para el grafo y los
vrtices (4, 6, 9, 7):
Solucin: a) 4-ciclo
b) Simple de longitud 3

CONCEPTOS BSICOS

Una cadena simple entre dos vrtices vi, vj es


una sucesin ordenada de vrtices del grafo
que cumplen las siguientes condiciones:
a) El primer vrtice es vi.
b) El ltimo vrtice es vj.
c) Cualquier par de vrtices vp, vq cumplen la
condicin de que o bien (vp, vq) o bien (vq,
vp) es un arco del grafo y todos los vrtices
son distintos excepto posiblemente el primero
y el ltimo.

Subgrafo G: de un grafo G = {V, A} es un


par G = (V, A) donde VV y
A A

CONCEPTOS BSICOS
CONEXIN:

Un grafo dirigido es fuertemente


conexo si existe un camino entre
cualquier par de nodos que forman el
grafo.

Un grafo dirigido es conexo si existe


una cadena que une cualquier par de
vrtices.

Un grafo no dirigido G es conexo y


fuertemente conexo (se dice conexo)
si existe un camino entre cualquier par
de nodos que forman el grafo.

Un grafo completo es aquel que tiene


un arco para cualquier par de vrtices.

CONCEPTOS BSICOS
Ejemplo:
Analizar la conexin y completitud de
los siguientes grafos:

Solucin: Ninguno es completo.


a) Grafo conexo
b) Grafo fuertemente conexo
c) Grafo dirigido conexo

REPRESENTACIN DE GRAFOS

Debemos representar un n finito de vrtices


y de arcos que unen dos vrtices. Podemos
elegir:
a) Representacin secuencial, mediante
arrays: Matriz de adyacencia.
b) Representacin dinmica, multienlazada:
Lista de adyacencia.

Si G = {V, A} es un grafo de n nodos V =


{v1, v2, ..., vn} a los que suponemos
ordenados. La representacin de los arcos se
hace con una matriz A de n x n elementos aij
definida:
1 si hay un arco (vi, vj)
aij
0 si no hay arco (vi, vj)
la matriz se denomina matriz de
adyacencia. En ocasiones la matriz de
adyacencia es una matriz boolean en la que
el elemento aij es verdadero si existe arco (vi,
vj) y falso en caso contrario.

REPRESENTACIN DE GRAFOS

Sea el grafo dirigido siguiente:

Si el orden de los vrtices es {D, F, K, L, R},


la matriz de adyacencia ser:
Qu tipo de vrtice es K?

REPRESENTACIN DE GRAFOS

Sea el grafo no dirigido siguiente:

Si el orden de los vrtices es {1, 2, 3, 4, 5},


la matriz de adyacencia ser:

Matriz simtrica ya que cada arista (vi, vj)


se corresponde con los arcos (vi, vj) y (vj, vi).

REPRESENTACIN DE GRAFOS

En el grafo valorado y dirigido siguiente:

Si el orden de los vrtices es {Alicante,


Barcelona, Cartagena, Murcia, Reus}, la
matriz de pesos ser:

MATRIZ ADYACENCIA
Declaracin de tipos:
const
maxvert = 20;
type
indice = 1..maxvert;
a) Asociarse directamente a la matriz definiendo
vertice = string;
un tipo subrango que englobe todos los valores
= array [indice]
de losvertices
pesos. Cambiar
0..1 por of
esevertice;
tipo.
mtAdyace = array [indice, indice] of 0..1;
b) Definir un tipo arco como:
grafo = record
type
n: indice;
...
v: vertices;
A: mtAdyace
arco = record
end;
adye: boolean;
var G: grafo;
peso: real
end; tiene factor de peso numrico,
Si el grafo
cmo lo podemos declarar?
mtAdyace = array [indice, indice] of arco;

OPERACIONES DEL TAD GRAFO


Para la matriz de adyacencia:
interface
procedure Inicializa (var G: Grafo);
function Posicion (G: Grafo, x: string): integer;
procedure NuevoArco (var G: Grafo; v1, v2:
integer);
procedure BorraArco (var G: Grafo; v1, v2:
integer);
function Adyacente (G: Grafo; v1, v2: integer):
boolean;
procedure NuevoVert (var G: Grafo, x: string);
procedure BorraVert (var G: Grafo, x: string);
implementation
procedure Inicializa;
begin
G.n := 0
end;

OPERACIONES DEL TAD GRAFO


procedure NuevoArco;
begin
G.A[v1, v2] := 1;
end;
procedure BorraArco;
begin
G.A[v1, v2] := 0;
end;
function Adyacente;
begin
Adyancente := G.A[v1, v2] = 1;
end;
procedure NuevoArco (var G: Grafo; v1, v2:
integer; w: real);
begin
G.A[v1, v2].adye := true;
G.A[v1, v2].peso := w;
end;

OPERACIONES DEL TAD GRAFO


procedure NuevoVert (var G: Grafo; x: string);
var i: integer;
begin
with G do
begin
if n < maxvert then {Llenos los arrays?}
begin
n := n+1; v[n] := x;
for i := 1 to n do {Inicializa la matriz de
begin
adyacencia con el nuevo vrtice}
G.A[i, n] := 0;
G.A[n, i] := 0
end;
end
else writeln (Error: no es posible nuevos
nodos);
end
end;

OPERACIONES DEL TAD GRAFO


function Posicion (G: Grafo; x: string): integer;
{Devuelve la posicin de un vrtice en el grafo o la
constante 1 si no est}
var i, p: integer;
begin
p := -1; i := 0;
while (i < G.n) and (p = -1) do
begin
i := i +1;
if G.v[i] = x then p := i
end;
Posicion := p
end;

OPERACIONES DEL TAD GRAFO


procedure BorraVert (var G: Grafo; x: string);
var i, p, c: integer;
begin
p := Posicion (G, x);
with G do
begin
if p in [1..G.n] then
begin
{Elimina el vrtice x}
for i := p to n-1 do v[i] := v[i +1];
{Ajuste de matriz de adyacencia}
for c := p to n-1 do {Desplaza columnas}
for i := 1 to n do A[i, c] := A[i, c+1];
for i := p to n-1 do {Desplaza filas}
for c:= 1 to n do A[i, c] := A[i+1, c]
n := n-1;
end
else writeln (Vrtice no existe en el grafo);
end
end;

REPRESENTACIN DE GRAFOS
Desventajas de la matriz de adyacencia:
La matriz de adyacencia puede resultar poco
eficiente en los siguientes casos:
a) Cuando el nmero de vrtices vare a lo largo
del proceso, sucediendo que sea mayor del
previsto.
b) Cuando el grafo es disperso, tiene pocos arcos.
Esto hace que la matriz tenga muchos ceros y
ocupa el mismo espacio que si el grafo tuviera
muchos arcos.
Las listas de adyacencia son una estructura
multienlazada formada por una lista directorio
cuyos nodos representan los vrtices del grafo y
de cada nodo tambin emerge una lista enlazada
cuyos nodos representan los arcos con vrtice
origen el del nodo de la lista directorio.

REPRESENTACIN DE GRAFOS

Sea el grafo dirigido siguiente:

La representacin de este grafo mediante


listas de adyacencia ser:

LISTA ADYACENCIA

Declaracin de tipos:
Cada nodo de la lista directorio almacena el
vrtice al que representa, la direccin de acceso
a la lista de adyacencia y la direccin del nodo
siguiente de la lista directorio.

type
tDir = ^NodoDir;
tAdy = ^NodoLy;
NodoDir = record
vertice: string;
plista: tAdy;
sig: tDir
end;

LISTA ADYACENCIA

Declaracin de tipos:
Cada nodo de la lista de adyacencia de un
vrtice del grafo almacena la direccin del
vrtice (en la lista directorio) con el que forma
un arco, en caso de ser un grafo valorado
tambin el factor peso, y como en todas las
listas la direccin del nodo siguiente.

type
NodoLy = record
pvert: tDir;
peso: real;
sig: tAdy
end;
var G: tDir;

OPERACIONES DEL TAD GRAFO


Para la lista de adyacencia:
interface
procedure Inicializa (var G: tDir);
funcion Direccion (G: tDir; x: string): tDir;
procedure NuevoArco (var G: tDir; v1, v2: string);
procedure BorraArco (var G: tDir; v1, v2: string);
function Adyacente (G: tDir; v1, v2:string):boolean;
procedure NuevoVert (var G: tDir; x: string);
procedure BorraVert (var G: tDir; x: string);
implementation
procedure Inicializa;
begin
G := nil;
end;

OPERACIONES DEL TAD GRAFO


Funciones auxiliares:
function CreaVert (x: string): tDir;
{Crea un nodo de la lista directorio}
var v: tDir;
begin
new (v); v^.vertice := x; v^.plista := nil;
v^.sig := nil; CreaVert := v
end;
procedure NuevoNodoLista (Q: tDir): tAdy;
var L: tAdy; {Crea un nodo de una lista enlazada
begin
adyacente. No es grafo valorado}
new (L); L^.pvert := Q; L^.sig := nil;
NuevoNodoLista := L
end;
procedure Anterior (G, P: tDir): tDir;
begin
while G^.sig <> P do G := G^.sig;
Anterior := G {Devuelve un puntero al nodo Anterior a
una direccin dada en la lista directorio}
end;

OPERACIONES DEL TAD GRAFO

Funciones auxiliares:
function libera (L: tAdy); {Borra todos los
var aux: tAdy;
elementos de una lista
begin
enlazada adyacente}
while L <> nil do
begin
aux := L; L:= L^.sig;
dispose (aux)
end;
function Ultimo (L: tAdy): tAdy; {Devuelve el
begin
ptro. al ltimo nodo de una
if L <> nil then
lista enlazada adyacente}
while L^.sig <> nil do L := L^.sig
Ultimo := L
end;
function UltimoV (D: tDir): tDir; {Devuelve el
begin
ptro. al ltimo nodo de la
if D <> nil then
lista directorio}
while D^.sig <> nil do D := D^.sig
UltimoV := D
end;

OPERACIONES DEL TAD GRAFO


function Direccion (G: tDir; x: string): tDir;
var P, D: tDir; {Devuelve un ptro. al nodo en el
begin que se encuentra el vrtice pasado como
P := nil; D := G; argumento, dentro de la lista
while (P = nil) and (D <> nil) do directorio}
if D^.vertice = x then P:= D
else D := D^.sig;
Direccion := P
end;
procedure NuevoArco (var G: tDir; v1, v2: string);
var P, Q: tDir;
begin
P:= Direccion (G, v1); Q:= Direccion (G, v2);
if (P<>nil) and (Q<>nil) then
with P^ do
if plista = nil then plista:= NuevoNodoLista(Q)
else Ultimo(plista)^.sig := NuevoNodoLista(Q)
end;{Se aade al final de la lista enlazada
adyacente, si sta no est vaca}

OPERACIONES DEL TAD GRAFO


procedure BorraArco (var G: tDir; v1,v2: string);
var P, D: tDir; R, W: tAdy; Sw: boolean;
begin
P:= Direccion (G, v1); Q:= Direccion (G, v2);
if (P<>nil) and (Q<>nil) then
begin
R:= P^.plista; W:= nil; Sw:= false;
while (R <> nil) and not Sw do
if R^.pvertice = Q then
begin {Quito 1 elemento de la lista adyac.}
if W = nil then P^.plista := R^.sig
else W^.sig := R^.sig;{quito otro elemento}
dispose (R);
Sw := true;
end
else begin
W := R; R:= R^.sig
end;
end
end; Recorro la lista de adyacencia de v1, buscando el puntero a v2

OPERACIONES DEL TAD GRAFO


function Adyacente (G: tDir; v1,v2: string):
boolean;
var P, Q: tDir; R: tAdy; Sw: boolean;
begin
P:= Direccion (G, v1); Q:= Direccion (G, v2);
if (P< >nil) and (Q< >nil) then
begin
{Proceso de bsqueda}
R:= P^.plista; Sw:= false;
while (R < > nil) and not Sw do
begin
Sw := R^.pvertice = Q;
if not Sw then R := R^.sig
end;
Adyacente := Sw;
end {Primer if}
else Adyacente := false; {Si algn vrtice no est
end;
en la lista directorio}

OPERACIONES DEL TAD GRAFO


procedure NuevoVert (var G: tDir; x: string);
begin {El vrtice se aade al final si la lista directorio no est
if G <>nil then UltimoV(G)^.sig := CreaVert(x)
vaca}
else G:= CreaVert (x)
end;
procedure BorraVert (var G: tDir; x: string);
var P, Q: tDir;
begin
P:= Direccion (G, x);
if (P <> nil) then
begin
Q := G;
while Q <> nil do
begin {Borra cualquier nodo donde aparezca x en las
BorraArco (G, Q^.vertice, x); listas enlazadas ady.}
Q := Q^.sig
end;
{Ahora elimina el nodo de la lista directorio}
if G = P then G := G^.sig
else Anterior (G, P)^.sig := P^.sig;
libera (P^.plista) {Borra toda la lista enlazada adyacente
dispose (P)
asociada al vrtice}
end
end;

REPRESENTACIN DE GRAFOS
Ejercicio:
a) Dado el grafo:

Suponiendo la ordenacin

Calcular la matriz de adyacencia:

REPRESENTACIN DE GRAFOS
Ejercicio:
b) Dado el grafo:
Suponiendo la ordenacin
estndar.

Dibujar la lista de adyacencia:

RECORRIDO DE GRAFOS
La operacin de recorrer una estructura consiste
en visitar (procesar) cada uno de los nodos a
partir de uno dado.
Hay dos formas de recorrido:
a) Anchura
b) Profundidad
Recorrido en anchura: (2 estructuras auxiliares)
a) Una cola donde almacenar los vrtices hasta
ser procesados.
b) Una lista de vrtices visitados. Los nodos de
esta lista tienen como campos:
- Un puntero al vrtice correspondiente de la
lista directorio.
- Un valor de tipo lgico para marcar si el
vrtice ha sido visitado.
- Un puntero al siguiente elemento se la lista
de visitados.

RECORRIDO DE GRAFOS
Recorrido en anchura:
Tenemos el grafo:

Se parte del vrtice D.


Pasos:
1. Se retira el frente de la cola.
2. Se meten en la cola los vrtices adyacentes
al frente no procesados.
3. Se vuelve a 1.

RECORRIDO DE GRAFOS
Tipos de datos auxiliares:
type
ptrnodoq = ^Nodoq;
Nodoq = record
Info: string;
Sig: ptrnodoq
end;
Cola = record
Frente, Final: ptrnodoq
end;
ptrlista = ^Nodol;
Nodol = record
V:
tDir;
Vsdo: boolean;
Sig : ptrlista
end;

COLA

LISTA VISITADA

RECORRIDO DE GRAFOS
procedimiento Anchura (Grafo,
Puntero al vrtice desde el que empieza recorrido)
1.- Procedimiento Lvisitada que crea una lista de punteros
con todos los campos visitados a false.
2.- Funcin Direccion que devuelve un puntero al nodo de la
lista visitada donde se encuentra el nodo que apunta al nodo
de la lista directorio pasado como argumento.

pasos del programa principal:


a) Llamar a 1
b) Inicializar la cola
c) Meter en la cola el pvrtice desde el que
empieza el recorrido que se pasa como segundo
argumento.
d) Bucle hasta que la cola queda vaca:
- Saca el frente de la cola que es el pvrtice visitado.
- Obtiene su lista de adyacencia.
- Recorre la lista de adyacencia:
1) Se recoge el ptro. a la lista directorio.
2) Se llama a 2 para tener la direccin en la lista visitados.
3) Se comprueba si esa direccin ha sido visitada:
No: se mete en la cola y se pone su campo visitado a true.
S: se comprueba el siguiente nodo en la lista de adyacencia

RECORRIDO DE GRAFOS

procedure Anchura (G, W: tDir);


var
Lv, Av: ptrlista; {Crea una lista de punteros a los
nodos de G con todos los campos
Q: Cola;
visitado igual a false}
N: tDir; L: tAdy;
procedure Lvisitada (var Lv: ptrlista; G: tDir);
var P: ptrlista;
function CreaV (Q: tDir): ptrlista;
var A: ptrlista;
begin
new (A); A^.V := Q; A^.Vsdo:= false;
CrearV := A
end;
begin {Lvisitada}
if (G<>nil) then
begin
Lv:= CreaV(G); P := Lv; G := G^.sig;
while (G <> nil) do
begin
P^.Sig := CreaV (G);
P := P^.Sig; G := G^.sig;
end // end // end; (Sigue)

RECORRIDO DE GRAFOS

function Direccion (L: ptrlista; W: tDir): ptrlista;


var {Devuelve un ptro. al nodo de la lista visitada
P, D: ptrlista; donde est el nodo que apunta al
begin nodo de la lista directorio pasado como arg}
P:= nil; D:= L;
while (P = nil) and (D <> nil) do
if D^.V = W then P:= D
else D := D^.Sig;
Direccion := P
end;
begin {Recorrido en Anchura}
Lvisitada (Lv, G);
Inicia (Q);
Encolar (W, Q); Direccion(Lv, W)^.Vsdo := true;
repeat
Desencolar (W, Q);
L := W^.plista;
while L<>nil do{Recorre la lista enlazada ady.}
begin
N := L^.pvert; Av := Direccion (Lv, N);
if not Av^.Vsdo then (Sigue)

RECORRIDO DE GRAFOS
begin
Encolar (N, Q);
Av^.Vsdo := true
end;
L := L^.sig
end;
until EsVacia(Q)
end;
Si se quieren visitar todos los vrtices del grafo,
una vez terminado el recorrido a partir de uno
dado (W) hay que buscar si queda algn vrtice
sin visitar en cuyo caso se vuelve a recorrer a
partir de l, as sucesivamente hasta que todos los
vrtices estn procesados.

RECORRIDO DE GRAFOS
Recorrido en profundidad:
Empieza por un vrtice que se marca como
visitado. Despus se visita hacia delante hasta
que sea posible.
Las estructuras auxiliares son:
a) Una pila donde almacenar los vrtices
adyacentes no procesados a uno dado.
b) Una lista de vrtices visitados. Los nodos de
esta lista tienen como campos:
- Un puntero al vrtice correspondiente de la
lista directorio.
- Un valor de tipo lgico para marcar si el
vrtice ha sido visitado.
- Un puntero al siguiente elemento de la lista
de visitados.

RECORRIDO DE GRAFOS
Recorrido en profundidad:
Tenemos el grafo:

Se parte del vrtice D.


Pasos:
1. Se retira la cima de la pila.
2. Se meten en la pila los vrtices adyacentes a
la cima no procesados.
3. Se vuelve a 1.

RECORRIDO DE GRAFOS
Tipos de datos auxiliares:
type
ptrnodop = ^Nodop;
Nodop = record
Info: string;
Sig: ptrnodop
end;
ptrlista = ^Nodol;
Nodol = record
V:
tDir;
Vsdo: boolean;
Sig : ptrlista
end;

PILA

LISTA VISITADA

RECORRIDO DE GRAFOS
procedimiento Profundidad (Grafo,
Puntero al vrtice desde el que empieza recorrido)
1.- Procedimiento Lvisitada que crea una lista de punteros
con todos los campos visitados a false.
2.- Funcin Direccion que devuelve un puntero al nodo de la
lista visitada donde se encuentra el nodo que apunta al nodo
de la lista directorio pasado como argumento.

pasos del programa principal:


a) Llamar a 1
b) Inicializar la pila
c) Meter en la pila el pvrtice desde el que empieza
el recorrido que se pasa como segundo argumento.
d) Bucle hasta que la pila queda vaca:
- Desapila la cima obteniendo el pvrtice visitado.
- Obtiene su lista de adyacencia.
- Recorre la lista de adyacencia:
1) Se recoge el ptro. a la lista directorio.
2) Se llama a 2 para tener la direccin en la lista visitados.
3) Se comprueba si esa direccin ha sido visitada:
No: se apila y se pone su campo visitado a true.
S: se comprueba el siguiente nodo en la lista de adyacencia

RECORRIDO DE GRAFOS

procedure Profundidad (G, W: tDir);


var
Lv, Av: ptrlista;
P: ptrnodop;
N: tDir; L: tAdy;
{Cdigo de procedimientos y funciones auxiliares, igual que
el recorrido anchura}
begin
Lvisitada (Lv, G);
Inicia (P);
Apliar (W, P); Direccion (Lv, W)^.Vsdo := true;
repeat
Desapilar (W, P); {Vrtice W visitado}
L := W^.plista;
while L<>nil do
begin
N := L^.pvert; Av := Direccion (Lv, N);
if not Av^.Vsdo then
begin
Apilar (N, P);
Av^.Vsdo := true
end;
L := L^.sig
end;
until EsVacia(P)
end;

RECORRIDO DE GRAFOS
procedimiento Profundidad (Grafo,
Puntero al vrtice desde el que empieza
recorrido)
pasos del programa principal:
a) Se pone a true el campo visitado del
vrtice pasado como argumento.
b) Se obtiene la lista de adyacencia del
vrtice pasado como argumento.
c) Bucle hasta que la lista de adyacencia se
vace:
- Caso Base: Que el elemento de la lista de
visitados tenga el campo visitado a true
- Caso recursivo: Que no se haya visitado el
elemento.

RECORRIDO DE GRAFOS
Realizacin recursiva:
procedure Profundidad (W: tDir; var Lv: ptrlista);
var L: tAdy;
begin
Direccion (Lv, W)^.Vsdo := true;
L := W^.plista;{Lista enlazada ady. del nodo W}
while L<>nil do
begin
if not Direccion (Lv, L^.pvert)^.Vsdo then
Profundidad (L^.pvert, Lv);
L := L^.sig
end
end;

RECORRIDO DE GRAFOS
Ejercicio:
Calcular los recorridos en anchura y
profundidad del siguiente grafo desde el
vrtice A:

Qu ocurre si empezamos desde D?


Solucin: (desde A)
Anchura:

{A, B, D, C, E}

Profundidad: {A, D, E, C, B}

COMPONENTES CONEXAS
Para comprobar si un grafo no dirigido es
conexo, se puede realizar un recorrido en anchura
o profundidad, que parta de un vrtice cualquiera
de l. Al final el grafo ser conexo si el conjunto
de vrtices visitados en el recorrido coincide con
todos los vrtices del grafo.
En el caso de grafos dirigidos, se define un grafo
G que contiene los mismos vrtices que G pero
todos sus arcos han pasado a ser aristas. Si (v1,
v2) est en G, entonces en G estarn (v1, v2) y
(v2, v1). G es conexo si lo es G (no dirigido).
Si un grafo no es conexo se pueden determinar
las componentes conexas que son subgrafos
disjuntos del grafo original que son cada uno de
ellos conexos.

COMPONENTES CONEXAS
Algoritmo para determinar las componentes
conexas de un grafo G no dirigido:
1. Recorrer el grafo desde cualquier vrtice w.
Los vrtices visitados se guardan en un conjunto
W.
2. Si W es el conjunto de todos los vrtices del
grafo, entonces el grafo es conexo.
3. Si el grafo no es conexo, W es una componente
conexa.
4. Se toma un vrtice no visitado, z, y se realiza
de nuevo el recorrido del grafo a partir de z. Los
vrtices visitados W forman otra componente
conexa.
5. El algoritmo termina cuando todos los vrtices
han sido visitados.

COMPONENTES CONEXAS

const M=100 {Mximo de vrtices}


type Conjunto = record
Vc: array [1..M] of string;
I: 0..M
end;
procedure Conexa (G, Z: tDir; var Lv: ptrlista; var
W: Conjunto);
var Av: ptrlista; Pila: ptrnodop; N: tDir; L: tAdy;
{Cdigo de procedimientos y funciones auxiliares,
igual que recorrido en profundidad}
begin
Inicia (Pila); Apilar (Z, Pila);
Direccion (Lv, Z)^.Vsdo := true;
repeat
Desapilar (Z, Pila);
with W do
begin
I := I+1;Vc[I] := Z^.vertice
end;
L := Z^.plista; {Lista de adyacencia de Z}

COMPONENTES CONEXAS

while L<> nil do


begin
N := L^.V; Av .= Direccion(Lv,N);
if not Av^.Vsdo then
begin
Apilar(N,Pila);
Av^.Vsdo .= true
end;
L := L^.sig
end
until Esvacia(Pila)
end;
procedure Componentes_Conexas(G: Grafo);
var T,W: Conjunto; Z: tDir; J, I: integer;
function DirNovis (L: ptrlista): ptrlista;
var D: ptrlista; Sw: boolean;
{Encuentra el nodo
de la lista de
begin
visitados que no ha
Sw := false; D := L;
sido visitado}
while (D<>nil) and not Sw do
begin
Sw := not D^.Vsdo;
if not Sw then D := D^.Sgte
end;
DirNovis .= D
end;

COMPONENTES CONEXAS

begin {Componentes_Conexas}
{En T guardamos el conjunto de todos los vrtices}
with T do
begin
I := 0; Z:=G;
while Z<>nil do
begin
I:= I +1; Vc [I] := Z^.vertices;
Z:= Z^.sig
end;
LVisitada (Lv, G); {Todos los vrtices a false en campo
Z:= DirNovis (Lv);
visitado}
while Z<>nil do
begin
W.I:= 0;
Conexa (G, Z, Lv, W);
if W.I = T.I then writeln (Grafo conexo); {Grafo conexo}
for J:= 1 to W.I do write (W.Vc [J], ); {Componente
writeln
conexa}
end;
Z := DirNovis (Lv)
end
end;

COMPONENTES FUERTEMENTE
CONEXAS
Un grafo dirigido fuertemente conexo es aquel en
el que existe un camino entre cualquier pareja de
vrtices del grafo.
De no ser fuertemente conexo se pueden
determinar las componentes fuertemente conexas
del grafo.

COMPO. FUERTEMENTE CONEXAS


Algoritmo para determinar las componentes
fuertemente conexas de un grafo G dirigido:
1. Obtener el conjunto de descendientes de un
vrtice de partida v, D(v), incluido el propio
vrtice v. As, tenemos todos los vrtices desde
los que hay un camino que comienza en v.

2. Obtener el conjunto de ascendientes de v, A(v),


incluido el propio vrtice v. Estos vrtices son
Para
el paso
construirunotro
grafoque
Gi llega
que
aquellos
en 2loshay
queque
comienza
camino
a v.resultado de invertir las direcciones de todos
sea
los arcos de G y despus recorrerlo.
3. Los vrtices comunes que tienen D y A, es
decir D(v) A(v), es el conjunto de vrtices de
la componente fuertemente conexa a la que
pertenece v. Si este conjunto es igual al conjunto
de vrtices de G, entonces el grafo es fuertemente
conexo.
4. Si no es un grafo fuertemente conexo se
selecciona un vrtice cualquiera w que no est en
ninguna componente fuerte de las encontradas y
se repite todo desde 1 hasta encontrar todas las
componentes fuertes del grafo.

COMPO. FUERTEMENTE CONEXAS


program ComponentesFuertes (input, output);
const n = 100;
type
Vertice = 1..n;
tDir = ^NodoDir;
tAdy = ^NodoLy;
NodoDir = record
Vertice: Vertice; {Identificador del vrtice}
plista: tAdy;
sig: tDir
end;
NodoLy = record
pvert: tDir;
sig: tAdy
end;
Visitados = array [Vertice] of boolean;
var
G, InvG: tDir;
Vstdos, Fuertes, Descendientes, Ascendientes,
Proc, Nulo: Visitados;
NumVerts, I, J: integer;

COMPO. FUERTEMENTE CONEXAS


procedure ListaDirectorio (var G: tDir; NumVerts:
integer); {Aadir vrtices a una lista directorio
var J: integer;
vaca}
begin
G:= nil;
for J := 1 to NumVerts do
NuevoVert (G, J); {Operacin definida en el
end;
TAD grafo de listas}
procedure Arcos (var G, Gi: tDir; NumVerts:
vertice);
{Crea los arcos del grafo
type Arco = record
dirigido y de su inverso}
x, y: vertice
end;
var U: Arco;
begin
write (Arcos par ordenado de vrtices? (fin eof):');
while not eof do
begin
read (U.x, U.y); NuevoArco (G, U.x, U.y);
NuevoArco (Gi, U.y, U.x);
end
end;

COMPO. FUERTEMENTE CONEXAS


procedure profundidad (G: tDir; V: Vertice; var Ac:
Visitados);
var L: tAdy;
begin
Vstdos[V] := true; Ac[V]:=true;
while L<>nil do
begin
if not Vstdos[L^.pvert^.vertice] then
profundidad (L^.pvert, L^.pvert^.vertice, Ac);
L:= L^.sig
end;
function Esconexo (Vs: Visitados; Nv: Vertice): boolean;
var J: integer; S: boolean;
begin
S:= true;
for J:= 1 to Nv do
S:= S and Vs [J];
Esconexo := S
end;
procedure Interseccion (D, A: Visitados; Nv: Vertice; var F:
Visitados);
var J: Vertice;
begin
for J:= 1 to Nv do
F[J]:= F[J] or (D[J] and A[J])
end;

COMPO. FUERTEMENTE CONEXAS


begin {programa principal}
write ('Numero de vertices: '); readln (NumVerts);
ListaDirectorio (G, NumVerts);
ListaDirectorio (InvG, NumVerts);
Arcos (G, InvG, NumVerts);
for I:= 1 to NumVerts do Nulo [I]:= false;
Fuertes:= Nulo; Proc:=Nulo;
for I:= 1 to NumVerts do
begin
if not Proc [I] then {Vrtice de partida cualquiera
begin que no est en ninguna componente obteni}
Vstdos:= Nulo; Descendientes:=Nulo;
Ascendientes:= Nulo;
profundidad (G, I, Descendientes);
Vstdos:= Nulo;
profundidad (InvG, I, Ascendientes);
Iterseccion (Descendientes, Ascendientes,
NumVerts, Fuertes);

COMPO. FUERTEMENTE CONEXAS


if Esconexo (Fuertes, NumVerts) then
begin
writeln ('El grafo es fuertemente conexo');
Proc:= Fuertes;
end
else begin
writeln ('Componente fuerte: ');
for J:=1 to NumVerts do
if Fuertes[J] then write (J, ' ');
writeln;
for J:= 1 to NumVerts do
Proc[J]:= Proc[J] or Fuertes[J];
Fuertes := Nulo; {Prepara para buscar otra
end;
componente fuerte}
end;
G:= G^.sig; InvG:= InvG^.sig;
end {del for}
end.

COMPONENTES FUERTEMENTE
CONEXAS
Ejercicio:
Calcular las componentes fuertemente
conexas del siguiente grafo:

Solucin: {F}
{S, C, B}
{M}

MATRIZ DE CAMINOS
Sea G un grafo de n vrtices y A su matriz de
adyacencia de tipo lgico. A[i, k] and A[k, j] es
cierta si hay un arco del vrtice i al k y otro del
k al j. Tambin indica que hay un camino de
longitud 2 del vrtice i al j.

La expresin:
(A[i,1] and A[1, j]) or (A[i, 2] and A[2, j]) or ...
or (A[i, NumVerts] and A[NumVerts, j])
ser cierta si hay al menos 1 camino de longitud
2 desde el vrtice i al j que pase a travs del
vrtice 1, o del 2, o del NumVerts.

Sustituyendo and por * y or por la +, la


expresin anterior es la del elemento aij del
producto matricial de AxA. Esto supone que los
elementos de A2 son true si existe un camino de
longitud 2 entre i y j para i, j =1..n
En general, para ver si existe un camino de
longitud m entre cualquier par de vrtices se
forma el producto booleano de los caminos de la
matriz Am-1 con la matriz de adyacencia A.

MATRIZ DE CAMINOS
Sea G un grafo de n vrtices y A su matriz de
adyacencia de tipo lgico:

MATRIZ DE CAMINOS
Sea G un grafo de n vrtices y A su matriz de
adyacencia de tipo lgico:

A15 es verdadero ya que hay un camino de


longitud 2 desde A-E (A B E)

MATRIZ DE CAMINOS
Si en lugar de la matriz con valores lgicos, se
obtiene la matriz con 0 y 1, el valor de calcular
las potencias de la matriz de adyacencia
representa el nmero de caminos de longitud k
desde el vrtice i al j.

NMERO DE CAMINOS

procedure Producto_A (A: MatAdcia; k: integer;


Nvs: Vertice; var Ak: MatAdcia);
var
I: integer;
procedure Prod (A, B: MatAdcia; var N:
MatAdcia);
var f, c, k, s: integer;
begin
for f := 1 to Nvs do
for c:= 1 to Nvs do
begin
s:= 0;
for k:= 1 to Nvs do
s := s + A[f, k] * B[c, k];
N [f, c] := s
end
end;
begin {Producto}
Ak := A;
for I := 2 to k do Prod (Ak, A, Ak)
end;

MATRIZ DE CAMINOS
Sea G un grafo de n vrtices. La matriz de
caminos de G es una matriz nxn definida: pij
vale 1 si hay un camino de vi a vj y cero en caso
contrario.

El camino de vi a vj ser:
a) Simple si vi<>vj con longitud n-1 o menor.
b) Ciclo si vi = vj con longitud n o menor.

Dada la matriz Bn = A + A2 + A3 + ...+ An, la


matriz de caminos P = (Pij) es tal que un
elemento Pij =1 Bn(i,j) = 1 y en otro caso Pij
= 0.
Otra forma de determinar que un grafo es
fuertemente conexo consiste en ver si su matriz
de caminos tiene todos los elementos a 1.

MATRIZ DE CAMINOS
Cierre transitivo:
De un grafo G es otro G que tiene los mismos
vrtices y que tiene como matriz de adyacencia
la matriz de caminos P del grafo G.
Segn esta definicin un grafo es fuertemente
conexo su cierre transitivo es un grafo
completo.
Ejercicio:
a) Cul es la matriz de caminos del siguiente
grafo?

b) es fuertemente conexo?

PUNTOS DE ARTICULACIN
Un punto de articulacin de un grafo no
dirigido es un vrtice V que si se elimina
junto a sus arcos, hace que la
componente conexa en que est el vrtice
se divide en dos o ms componentes.

Encontrar sus puntos de articulacin.

PUNTOS DE ARTICULACIN

Un grafo biconexo no tiene puntos de


articulacin.
Un grafo tiene conectividad k si la eliminacin
de k-1 vrtices cualesquiera del grafo no lo
divide en componentes conexas (no lo
desconecta).
Cuanto mayor sea la conectividad de un grafo
(una red por ejemplo), tanta mayor probabilidad
tendr de mantener la estructura ante el fallo
(eliminacin) de alguno de sus vrtices.

También podría gustarte