A graph is a data structure that represent a collection of vertices and edges, that store connectivity information,
I will show how to represent a graph in 2 ways, and two graph traversal algorithms dfs, bfs. Finally i will add the snippets to load a graph, and dfs, bfs algorithms in c++.
A Adjacency matrix: Is a connectivity table represented in a 2D matrix int AdjMat[v][v]. For an unweighted graph we can set AdjMat[i][j] = 1 if there is connectivity otherwise the weigth.
B Adjacency List: Is a vector of vector of pairs. Here we store the information of the nodes in pairs. Neighbor and weight.
Graph Traversal
This is a video that explains in a clearly way two graph traversal algorithms, Deep First Search, Breadth First Search.
Snippets
BFS
#include <iostream>#include <cstdio>#include <vector>#include <queue>#define MAXN 500usingnamespace std;
vector < vector <int>> graph(MAXN);
bool discovered[MAXN];//keeps track if a node has been reachedint parent[MAXN];//stores the nodes ancestor that discovered it for the first timeint distances[MAXN];//stores the distance to reach each node from the sourcevoidinit_graph(int vertices)
{
int i;
for(i =0; i < vertices; i++)
{
discovered[i] =false;
graph[i].clear();
distances[i] = parent[i] =-1;
}
}
voidread_graph(int edges)
{
int vertex1, vertex2;
int i;
for(i =0; i < edges; i++)
{
scanf("%d %d", &vertex1, &vertex2);
graph[vertex1].push_back(vertex2);
graph[vertex2].push_back(vertex1);
}
}
voidbfs(int start)
{
int current;//current node being processedint next;//reached node by currentunsignedint i;
queue<int> vertices;//vertices to process
distances[start] =0;
discovered[start] =true;
vertices.push(start);
while(!vertices.empty())
{
current = vertices.front();
vertices.pop();
for(i =0; i < graph[current].size(); i++)//for each node connected to current
{
next = graph[current][i];
if(!discovered[next])//if it hasn't been reached
{
discovered[next] =true;//mark it as reached
parent[next] = current;//store its parent
distances[next] = distances[current]+1;//save the distance
vertices.push(next);//push it to the queue for further analysis
}
}
}
}
voidfind_path(int vertex)//recursive procedure to find the path
{
if(vertex ==-1)
return;
find_path(parent[vertex]);
printf("%d ", vertex);
}
intmain()
{
int vertices;
int edges;
int start;
int dest_path;
int i;
scanf("%d %d", &vertices, &edges);
init_graph(vertices);
read_graph(edges);
scanf("%d", &start);
bfs(start);
for(i =0; i < vertices; i++)
printf("%d ",distances[i]);
printf("\n");
scanf("%d", &dest_path);
find_path(dest_path);
return0;
}
DFS
#include <algorithm>#include <cstdio>#include <vector>usingnamespace std;
typedef pair<int, int> ii; // In this chapter, we will frequently use thesetypedef vector<ii> vii; // three data type shortcuts. They may look cryptictypedef vector<int> vi; // but shortcuts are useful in competitive programming#define DFS_WHITE -1 // normal DFS, do not change this with other values (other than 0), because we usually use memset with conjunction with DFS_WHITE#define DFS_BLACK 1
vector<vii> AdjList;
voidprintThis(char* message) {
printf("==================================\n");
printf("%s\n", message);
printf("==================================\n");
}
vi dfs_num; // this variable has to be global, we cannot put it in recursionint numCC;
voiddfs(int u) { // DFS for normal usage: as graph traversal algorithm
printf(" %d", u); // this vertex is visited
dfs_num[u] = DFS_BLACK; // important step: we mark this vertex as visitedfor (int j =0; j < (int)AdjList[u].size(); j++) {
ii v = AdjList[u][j]; // v is a (neighbor, weight) pairif (dfs_num[v.first] == DFS_WHITE) // important check to avoid cycle
dfs(v.first); // recursively visits unvisited neighbors v of vertex u
} }
intmain() {
int V, total_neighbors, id, weight;
/* // Use the following input: // Graph in Figure 4.1 *///freopen("in_01.txt", "r", stdin);
scanf("%d", &V);
AdjList.assign(V, vii()); // assign blank vectors of pair<int, int>s to AdjListfor (int i =0; i < V; i++) {
scanf("%d", &total_neighbors);
for (int j =0; j < total_neighbors; j++) {
scanf("%d %d", &id, &weight);
AdjList[i].push_back(ii(id, weight));
}
}
printThis("Standard DFS Demo (the input graph must be UNDIRECTED)");
numCC =0;
dfs_num.assign(V, DFS_WHITE); // this sets all vertices' state to DFS_WHITEfor (int i =0; i < V; i++) // for each vertex i in [0..V-1]if (dfs_num[i] == DFS_WHITE) // if that vertex is not visited yet
printf("Component %d:", ++numCC), dfs(i), printf("\n"); // 3 lines here!return0;
}