Académique Documents
Professionnel Documents
Culture Documents
de Grafos
Universidad Latina de Costa Rica
Estructura de Datos II
1
Algoritmos de grafos
2
Representaciones de grafos
3
Representaciones de grafos
4
Representaciones de grafos
En C++, podemos usar un doble array para guardar la matriz de antes:
int A[6][6];
//inicializar todo a 0
for(int i=0;i<6;i++)
for(int j=0;j<6;j++)
A[i][j] = 0;
//1 si hay enlace origen -> destino
A[0][1] = 1;
A[1][2] = 1;
A[1][4] = 1;
A[2][4] = 1;
A[3][1] = 1;
A[4][3] = 1;
A[4][5] = 1;
A[5][2] = 1;
5
Representaciones de grafos
6
Representaciones de grafos
7
Representaciones de grafos
3. Lista de aristas: se guarda una lista de todas las aristas del grafo.
(0,1) (0,3) (1,2) (1,4) (2,4) (3,1) (4,3) (4,5) (5,2)
9
Representaciones de grafos
Algoritmos típicos
Los algoritmos de grafos que suelen aparecer son los típicos que se
enseñan en Algebra Lineal y Matemática Discreta:
Búsqueda BFS
Búsqueda DFS
Kruskal
Dijkstra
Floyd Warshall
Ford Fulkerson
10
Implementar el algoritmo de Kruskal
• Para implementar el algoritmo de Kruskal se puede aprovechar una
estructura que se llama "Union-Find" o "Merge-Find", que representa
una partición de un conjunto de valores (en este caso los nodos del
grafo). La idea es mantener un árbol para cada subconjunto, tal que la
raíz de cada árbol es el nodo representante para el subconjunto
correspondiente.
• Las únicas dos operaciones de la estructura son "Merge", que
combina dos árboles en uno, y "Find", que devuelve el nodo
representante para un nodo cualquiera. Para implementar esta
estructura es suficiente recordar cuál es el padre de cada nodo, lo que
se puede hacer con un simple array de enteros. Por defecto, la raíz de
un árbol es su propio padre.
11
Implementar el algoritmo de Kruskal
12
Implementar el algoritmo de Kruskal
int find(int n)
{
if (mf[n] == n)
return n;
else
return mf[n] = find(mf[n]);
}
13
Implementar el algoritmo de Kruskal
14
Implementar el algoritmo de Kruskal
Ahora podemos implementar el algoritmo de Kruskal de la siguiente
manera:
• Representar el grafo (no dirigido) por una lista de aristas
• Inicializar la estructura merge-find
• Recorrer la lista de aristas de menor a mayor coste
• Para cada arista (a,b), usamos "find" para encontrar el nodo
representante de a y b
• Si los nodos representantes son iguales, ignoramos la arista (crearía
un ciclo)
• Si los nodos representantes son diferentes, incluimos la arista y
usamos "merge" para combinar los dos subconjuntos
15
El algoritmo de Bellman Ford
Otro algoritmo común es uno que se llama Bellman Ford, que esencialmente es un Dijkstra para el caso de
que se permiten aristas con coste negativo.
El problema sigue siendo encontrar un camino de coste mínimo entre dos nodos del grafo. Sin embargo, el
coste mínimo podría ser -∞ si hay ciclos de coste negativo que se pueden recorrer.
Este caso se tiene que tratar aparte.
Igual que Kruskal, la mejor representación para Bellman Ford es la lista de aristas.
17
Ejemplos
Algoritmos de grafos
BFS: bfs.cpp
Kruskal: kruskal.cpp
Dijkstra: dijkstra.cpp
Floyd-Warshall: floydwarshall.cpp
Bellman-Ford: bellmanford.cpp
Ford-Fulkerson: fordfulkerson.cpp
18
Ejercicio
En el lenguaje C++ implemente un Grafo Dirigido en forma Enlazada con Lista de Adyacencia
/* Menu
---------------------------------------------------------------------*/
void menu()
{
cout<<"\n\tREPRESENTACION DE GRAFOS DIRIGIDOS\n\n";
cout<<" 1. INSERTAR UN NODO "<<endl;
cout<<" 2. INSERTAR UNA ARISTA "<<endl;
cout<<" 3. ELIMINAR UN NODO "<<endl;
cout<<" 4. ELIMINAR UNA ARISTA "<<endl;
cout<<" 5. MOSTRAR GRAFO "<<endl;
cout<<" 6. MOSTRAR ARISTAS DE UN NODO "<<endl;
cout<<" 7. SALIR "<<endl;
19
Ejercicio
struct nodo{
char nombre;//nombre del vertice o nodo
struct nodo *sgte;
struct arista *ady;//puntero hacia la primera arista del nodo
};
struct arista{
struct nodo *destino;//puntero al nodo de llegada
struct arista *sgte;
};
typedef struct nodo *Tnodo;// Tipo Nodo
typedef struct arista *Tarista; //Tipo Arista
void menu();
void insertar_nodo();
void agrega_arista(Tnodo &, Tnodo &, Tarista &);
void insertar_arista();
void vaciar_aristas(Tnodo &);
void eliminar_nodo();
void eliminar_arista();
void mostrar_grafo();
20
void mostrar_aristas();