0% found this document useful (0 votes)
15 views

Graphs overview

Uploaded by

gurly101
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
15 views

Graphs overview

Uploaded by

gurly101
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 38

Graphs overview

1. Definition

A graph is a collection of vertices (nodes) and edges (connections).

● Represented as G(V, E) where:


○ V = set of vertices.
○ E = set of edges connecting the vertices.

2. Basic Terminology

● Directed Graph: Edges have directions (e.g., one-way streets).


● Undirected Graph: Edges are bidirectional (e.g., two-way streets).
● Weighted Graph: Edges have weights (e.g., distance, cost).
● Unweighted Graph: All edges have the same weight.
● Adjacent: Two vertices are connected directly by an edge.
● Degree:
○ In-degree: Number of incoming edges to a vertex.
○ Out-degree: Number of outgoing edges from a vertex.
○ Total Degree: Sum of in-degrees and out-degrees.

3. Graph Types

● Simple Graph: No loops, no multiple edges.


● Multigraph: Multiple edges between the same set of vertices.
● Complete Graph: Every vertex is connected to every other vertex.
● Cyclic and Acyclic Graphs:
○ Cyclic: Graph contains at least one cycle.
○ Acyclic: Graph has no cycles (e.g., DAG - Directed Acyclic Graph).
● Connected Graph: There’s a path between every pair of vertices.
● Disconnected Graph: Not all vertices are connected.
● Tree: A connected acyclic graph.

4. Graph Representations

Static Representation
● Adjacency Matrix: 2D array where matrix[i][j] is 1 if there's an edge between i
and j.
○ Space Complexity: O(V2)O(V^2)O(V2).
○ Best For: Dense graphs.
● Adjacency List: Array of lists where list[i] contains all neighbors of vertex i.
○ Space Complexity: O(V+E)O(V + E)O(V+E).
○ Best For: Sparse graphs.

Dynamic Representation

● Using data structures like vector or map for adjacency lists, which grow dynamically.

5. Graph Implementations in C++

Adjacency Matrix
cpp
Copy code
#include <iostream>
using namespace std;
#define V 5

void printMatrix(int graph[V][V]) {


for (int i = 0; i < V; i++) {
for (int j = 0; j < V; j++)
cout << graph[i][j] << " ";
cout << endl;
}
}

int main() {
int graph[V][V] = { {0, 1, 0, 0, 1},
{1, 0, 1, 1, 0},
{0, 1, 0, 1, 1},
{0, 1, 1, 0, 1},
{1, 0, 1, 1, 0} };

printMatrix(graph);
return 0;
}
Adjacency List
cpp
Copy code
#include <iostream>
#include <vector>
using namespace std;

void addEdge(vector<int> adj[], int u, int v) {


adj[u].push_back(v);
adj[v].push_back(u); // For undirected graph
}

void printGraph(vector<int> adj[], int V) {


for (int i = 0; i < V; i++) {
cout << i << ": ";
for (int x : adj[i])
cout << x << " ";
cout << endl;
}
}

int main() {
int V = 5;
vector<int> adj[V];

addEdge(adj, 0, 1);
addEdge(adj, 0, 4);
addEdge(adj, 1, 2);
addEdge(adj, 1, 3);
addEdge(adj, 1, 4);
addEdge(adj, 2, 3);
addEdge(adj, 3, 4);

printGraph(adj, V);
return 0;
}
6. Graph Searching Algorithms

Depth-First Search (DFS)

● Recursive or using stack.


● Explores as far as possible along each branch before backtracking.

Breadth-First Search (BFS)

● Queue-based.
● Explores all neighbors before moving to the next level.

7. Shortest Path Algorithms

● Dijkstra’s Algorithm: For weighted graphs, no negative weights.


● Bellman-Ford Algorithm: Handles negative weights.
● Floyd-Warshall Algorithm: All-pairs shortest path.
● A Search*: Heuristic-based, efficient for pathfinding.

8. Applications of Graphs

1. Social Networks: Modeling connections.


2. Web Crawlers: Link structure of web pages.
3. Pathfinding: GPS and maps.
4. Network Flow: Communication networks.
5. Dependency Resolution: Task scheduling using DAG.
6. Game Development: AI pathfinding.

9. Important Practice Questions

1. Represent a graph using adjacency matrix and list.


2. Write a program for BFS and DFS traversal of a graph.
3. Implement Dijkstra’s Algorithm for shortest path.
4. Write a program to detect a cycle in a graph.
5. Find the connected components in an undirected graph.
6. Implement Floyd-Warshall for all-pairs shortest paths.
7. Implement topological sort using BFS/DFS.
8. Write a program to find bridges and articulation points.
9. Solve minimum spanning tree using Kruskal’s or Prim’s algorithm.
10. Apply graph coloring to solve problems like N-Queens or Sudoku Solver.

1. Graph Representation (Adjacency Matrix and List)

Adjacency Matrix

cpp

Copy code

#include <iostream>

using namespace std;

void printAdjMatrix(int **matrix, int V) {

for (int i = 0; i < V; i++) {

for (int j = 0; j < V; j++) {

cout << matrix[i][j] << " ";

cout << endl;

int main() {

int V = 5;

int **matrix = new int *[V];

for (int i = 0; i < V; i++) {


matrix[i] = new int[V]();

// Example graph

matrix[0][1] = 1; matrix[0][4] = 1;

matrix[1][0] = 1; matrix[1][2] = 1; matrix[1][3] = 1; matrix[1][4]


= 1;

matrix[2][1] = 1; matrix[2][3] = 1;

matrix[3][1] = 1; matrix[3][2] = 1; matrix[3][4] = 1;

matrix[4][0] = 1; matrix[4][1] = 1; matrix[4][3] = 1;

cout << "Adjacency Matrix:\n";

printAdjMatrix(matrix, V);

for (int i = 0; i < V; i++) delete[] matrix[i];

delete[] matrix;

return 0;

Adjacency List

cpp

Copy code
#include <iostream>

using namespace std;

struct Node {

int data;

Node *next;

};

void addEdge(Node **adjList, int u, int v) {

Node *newNode = new Node{v, adjList[u]};

adjList[u] = newNode;

newNode = new Node{u, adjList[v]};

adjList[v] = newNode;

void printAdjList(Node **adjList, int V) {

for (int i = 0; i < V; i++) {

cout << i << ": ";

Node *temp = adjList[i];

while (temp) {

cout << temp->data << " ";

temp = temp->next;
}

cout << endl;

int main() {

int V = 5;

Node **adjList = new Node *[V];

for (int i = 0; i < V; i++) adjList[i] = nullptr;

addEdge(adjList, 0, 1);

addEdge(adjList, 0, 4);

addEdge(adjList, 1, 2);

addEdge(adjList, 1, 3);

addEdge(adjList, 1, 4);

addEdge(adjList, 2, 3);

addEdge(adjList, 3, 4);

cout << "Adjacency List:\n";

printAdjList(adjList, V);

for (int i = 0; i < V; i++) {

Node *temp = adjList[i];


while (temp) {

Node *delNode = temp;

temp = temp->next;

delete delNode;

delete[] adjList;

return 0;

2. BFS and DFS Traversal

BFS

cpp

Copy code

#include <iostream>

#include <queue>

using namespace std;

void bfs(int **matrix, int V, int start) {

bool *visited = new bool[V]();

queue<int> q;
visited[start] = true;

q.push(start);

cout << "BFS Traversal: ";

while (!q.empty()) {

int node = q.front();

q.pop();

cout << node << " ";

for (int i = 0; i < V; i++) {

if (matrix[node][i] && !visited[i]) {

visited[i] = true;

q.push(i);

cout << endl;

delete[] visited;

int main() {

int V = 5;
int **matrix = new int *[V];

for (int i = 0; i < V; i++) {

matrix[i] = new int[V]();

matrix[0][1] = 1; matrix[0][4] = 1;

matrix[1][0] = 1; matrix[1][2] = 1; matrix[1][3] = 1; matrix[1][4]


= 1;

matrix[2][1] = 1; matrix[2][3] = 1;

matrix[3][1] = 1; matrix[3][2] = 1; matrix[3][4] = 1;

matrix[4][0] = 1; matrix[4][1] = 1; matrix[4][3] = 1;

bfs(matrix, V, 0);

for (int i = 0; i < V; i++) delete[] matrix[i];

delete[] matrix;

return 0;

DFS

cpp

Copy code
#include <iostream>

using namespace std;

void dfsHelper(int **matrix, bool *visited, int V, int node) {

visited[node] = true;

cout << node << " ";

for (int i = 0; i < V; i++) {

if (matrix[node][i] && !visited[i]) {

dfsHelper(matrix, visited, V, i);

void dfs(int **matrix, int V, int start) {

bool *visited = new bool[V]();

cout << "DFS Traversal: ";

dfsHelper(matrix, visited, V, start);

cout << endl;

delete[] visited;

int main() {
int V = 5;

int **matrix = new int *[V];

for (int i = 0; i < V; i++) {

matrix[i] = new int[V]();

matrix[0][1] = 1; matrix[0][4] = 1;

matrix[1][0] = 1; matrix[1][2] = 1; matrix[1][3] = 1; matrix[1][4]


= 1;

matrix[2][1] = 1; matrix[2][3] = 1;

matrix[3][1] = 1; matrix[3][2] = 1; matrix[3][4] = 1;

matrix[4][0] = 1; matrix[4][1] = 1; matrix[4][3] = 1;

dfs(matrix, V, 0);

for (int i = 0; i < V; i++) delete[] matrix[i];

delete[] matrix;

return 0;

3. Dijkstra's Algorithm for Shortest Path


cpp
Copy code
#include <iostream>
#include <climits>
using namespace std;

int findMinDistance(int *dist, bool *visited, int V) {


int minDist = INT_MAX, minIndex = -1;
for (int i = 0; i < V; i++) {
if (!visited[i] && dist[i] < minDist) {
minDist = dist[i];
minIndex = i;
}
}
return minIndex;
}

void dijkstra(int **graph, int V, int start) {


int *dist = new int[V];
bool *visited = new bool[V]();

for (int i = 0; i < V; i++) dist[i] = INT_MAX;


dist[start] = 0;

for (int i = 0; i < V - 1; i++) {


int u = findMinDistance(dist, visited, V);
visited[u] = true;

for (int v = 0; v < V; v++) {


if (!visited[v] && graph[u][v] && dist[u] != INT_MAX &&
dist[u] + graph[u][v] < dist[v]) {
dist[v] = dist[u] + graph[u][v];
}
}
}

cout << "Vertex\tDistance from Source\n";


for (int i = 0; i < V; i++) {
cout << i << "\t" << dist[i] << endl;
}
delete[] dist;
delete[] visited;
}

int main() {
int V = 5;
int **graph = new int *[V];
for (int i = 0; i < V; i++) {
graph[i] = new int[V]();
}

// Example graph
graph[0][1] = 10; graph[0][4] = 5;
graph[1][2] = 1; graph[1][4] = 2;
graph[2][3] = 4;
graph[3][0] = 7; graph[3][2] = 6;
graph[4][1] = 3; graph[4][2] = 9; graph[4][3] = 2;

dijkstra(graph, V, 0);

for (int i = 0; i < V; i++) delete[] graph[i];


delete[] graph;

return 0;
}

4. Floyd-Warshall Algorithm
cpp
Copy code
#include <iostream>
#include <climits>
using namespace std;

void floydWarshall(int **graph, int V) {


int **dist = new int *[V];
for (int i = 0; i < V; i++) {
dist[i] = new int[V];
for (int j = 0; j < V; j++) {
dist[i][j] = (graph[i][j] == 0 && i != j) ? INT_MAX :
graph[i][j];
}
}

for (int k = 0; k < V; k++) {


for (int i = 0; i < V; i++) {
for (int j = 0; j < V; j++) {
if (dist[i][k] != INT_MAX && dist[k][j] != INT_MAX &&
dist[i][k] + dist[k][j] < dist[i][j]) {
dist[i][j] = dist[i][k] + dist[k][j];
}
}
}
}

cout << "Shortest distances between all pairs:\n";


for (int i = 0; i < V; i++) {
for (int j = 0; j < V; j++) {
if (dist[i][j] == INT_MAX)
cout << "INF ";
else
cout << dist[i][j] << " ";
}
cout << endl;
}

for (int i = 0; i < V; i++) delete[] dist[i];


delete[] dist;
}

int main() {
int V = 4;
int **graph = new int *[V];
for (int i = 0; i < V; i++) {
graph[i] = new int[V];
for (int j = 0; j < V; j++) {
graph[i][j] = (i == j) ? 0 : INT_MAX;
}
}

graph[0][1] = 3; graph[0][3] = 5;
graph[1][0] = 2; graph[1][3] = 4;
graph[2][1] = 1;
graph[3][2] = 2;

floydWarshall(graph, V);

for (int i = 0; i < V; i++) delete[] graph[i];


delete[] graph;

return 0;
}

5. Topological Sort using DFS


cpp
Copy code
#include <iostream>
#include <stack>
using namespace std;

void topologicalSortDFS(int **graph, bool *visited, stack<int> &st,


int V, int node) {
visited[node] = true;

for (int i = 0; i < V; i++) {


if (graph[node][i] && !visited[i]) {
topologicalSortDFS(graph, visited, st, V, i);
}
}
st.push(node);
}
void topologicalSort(int **graph, int V) {
stack<int> st;
bool *visited = new bool[V]();

for (int i = 0; i < V; i++) {


if (!visited[i]) {
topologicalSortDFS(graph, visited, st, V, i);
}
}

cout << "Topological Order: ";


while (!st.empty()) {
cout << st.top() << " ";
st.pop();
}
cout << endl;

delete[] visited;
}

int main() {
int V = 6;
int **graph = new int *[V];
for (int i = 0; i < V; i++) {
graph[i] = new int[V]();
}

graph[5][2] = 1; graph[5][0] = 1;
graph[4][0] = 1; graph[4][1] = 1;
graph[2][3] = 1;
graph[3][1] = 1;

topologicalSort(graph, V);

for (int i = 0; i < V; i++) delete[] graph[i];


delete[] graph;

return 0;
}

. Find Bridges and Articulation Points in a Graph

Bridges in a Graph
cpp
Copy code
#include <iostream>
#include <cstring>
using namespace std;

void dfsBridge(int **graph, int V, int u, int parent, int *disc, int
*low, bool *visited) {
static int time = 0;
visited[u] = true;
disc[u] = low[u] = ++time;

for (int v = 0; v < V; v++) {


if (graph[u][v]) {
if (!visited[v]) {
dfsBridge(graph, V, v, u, disc, low, visited);

low[u] = min(low[u], low[v]);


if (low[v] > disc[u]) {
cout << "Bridge: " << u << " - " << v << endl;
}
} else if (v != parent) {
low[u] = min(low[u], disc[v]);
}
}
}
}

void findBridges(int **graph, int V) {


int *disc = new int[V]();
int *low = new int[V]();
bool *visited = new bool[V]();

for (int i = 0; i < V; i++) {


if (!visited[i]) {
dfsBridge(graph, V, i, -1, disc, low, visited);
}
}

delete[] disc;
delete[] low;
delete[] visited;
}

int main() {
int V = 5;
int **graph = new int *[V];
for (int i = 0; i < V; i++) {
graph[i] = new int[V]();
}

// Example graph
graph[0][1] = 1; graph[1][0] = 1;
graph[1][2] = 1; graph[2][1] = 1;
graph[1][3] = 1; graph[3][1] = 1;
graph[3][4] = 1; graph[4][3] = 1;

findBridges(graph, V);

for (int i = 0; i < V; i++) delete[] graph[i];


delete[] graph;

return 0;
}

Articulation Points in a Graph


cpp
Copy code
#include <iostream>
#include <cstring>
using namespace std;
void dfsArticulation(int **graph, int V, int u, int parent, int *disc,
int *low, bool *visited, bool *ap) {
static int time = 0;
visited[u] = true;
disc[u] = low[u] = ++time;
int children = 0;

for (int v = 0; v < V; v++) {


if (graph[u][v]) {
if (!visited[v]) {
children++;
dfsArticulation(graph, V, v, u, disc, low, visited,
ap);

low[u] = min(low[u], low[v]);


if (parent == -1 && children > 1) ap[u] = true;
if (parent != -1 && low[v] >= disc[u]) ap[u] = true;
} else if (v != parent) {
low[u] = min(low[u], disc[v]);
}
}
}
}

void findArticulationPoints(int **graph, int V) {


int *disc = new int[V]();
int *low = new int[V]();
bool *visited = new bool[V]();
bool *ap = new bool[V]();

for (int i = 0; i < V; i++) {


if (!visited[i]) {
dfsArticulation(graph, V, i, -1, disc, low, visited, ap);
}
}

cout << "Articulation Points: ";


for (int i = 0; i < V; i++) {
if (ap[i]) cout << i << " ";
}
cout << endl;

delete[] disc;
delete[] low;
delete[] visited;
delete[] ap;
}

int main() {
int V = 5;
int **graph = new int *[V];
for (int i = 0; i < V; i++) {
graph[i] = new int[V]();
}

// Example graph
graph[0][1] = 1; graph[1][0] = 1;
graph[1][2] = 1; graph[2][1] = 1;
graph[1][3] = 1; graph[3][1] = 1;
graph[3][4] = 1; graph[4][3] = 1;

findArticulationPoints(graph, V);

for (int i = 0; i < V; i++) delete[] graph[i];


delete[] graph;

return 0;
}

7. Minimum Spanning Tree using Prim's Algorithm


cpp
Copy code
#include <iostream>
#include <climits>
using namespace std;

int findMinKey(int *key, bool *mstSet, int V) {


int minKey = INT_MAX, minIndex = -1;
for (int i = 0; i < V; i++) {
if (!mstSet[i] && key[i] < minKey) {
minKey = key[i];
minIndex = i;
}
}
return minIndex;
}

void primMST(int **graph, int V) {


int *parent = new int[V];
int *key = new int[V];
bool *mstSet = new bool[V]();

for (int i = 0; i < V; i++) key[i] = INT_MAX;


key[0] = 0;
parent[0] = -1;

for (int i = 0; i < V - 1; i++) {


int u = findMinKey(key, mstSet, V);
mstSet[u] = true;

for (int v = 0; v < V; v++) {


if (graph[u][v] && !mstSet[v] && graph[u][v] < key[v]) {
parent[v] = u;
key[v] = graph[u][v];
}
}
}

cout << "Edge \tWeight\n";


for (int i = 1; i < V; i++) {
cout << parent[i] << " - " << i << " \t" <<
graph[i][parent[i]] << endl;
}

delete[] parent;
delete[] key;
delete[] mstSet;
}

int main() {
int V = 5;
int **graph = new int *[V];
for (int i = 0; i < V; i++) {
graph[i] = new int[V];
}

// Example graph
graph[0][1] = 2; graph[0][3] = 6;
graph[1][0] = 2; graph[1][2] = 3; graph[1][3] = 8; graph[1][4] =
5;
graph[2][1] = 3; graph[2][4] = 7;
graph[3][0] = 6; graph[3][1] = 8; graph[3][4] = 9;
graph[4][1] = 5; graph[4][2] = 7; graph[4][3] = 9;

primMST(graph, V);

for (int i = 0; i < V; i++) delete[] graph[i];


delete[] graph;

return 0;
}

8. Graph Coloring with N-Queens Problem

The N-Queens Problem is a classic example of graph coloring, where each queen represents a
node, and we aim to "color" nodes (place queens) such that no two queens threaten each other.

Here’s the C++ code for solving the N-Queens problem:

N-Queens Solver using Backtracking


cpp
Copy code
#include <iostream>
using namespace std;

#define N 8 // Change this for different board sizes

bool isSafe(int board[N][N], int row, int col) {


// Check left side of the row
for (int i = 0; i < col; i++) {
if (board[row][i]) return false;
}

// Check upper diagonal on the left side


for (int i = row, j = col; i >= 0 && j >= 0; i--, j--) {
if (board[i][j]) return false;
}

// Check lower diagonal on the left side


for (int i = row, j = col; j >= 0 && i < N; i++, j--) {
if (board[i][j]) return false;
}

return true;
}

bool solveNQueensUtil(int board[N][N], int col) {


if (col >= N) return true; // All queens placed successfully

for (int i = 0; i < N; i++) {


if (isSafe(board, i, col)) {
board[i][col] = 1; // Place the queen

if (solveNQueensUtil(board, col + 1)) {


return true;
}

board[i][col] = 0; // Backtrack
}
}

return false; // No solution found for this configuration


}

void printSolution(int board[N][N]) {


for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
cout << (board[i][j] ? "Q " : ". ");
}
cout << endl;
}
}

void solveNQueens() {
int board[N][N] = {0};

if (!solveNQueensUtil(board, 0)) {
cout << "No solution exists." << endl;
} else {
printSolution(board);
}
}

int main() {
solveNQueens();
return 0;
}

Explanation of the Code:

1. Safety Check (isSafe):


○ Ensures no queen threatens another on the same row, upper-left diagonal, or
lower-left diagonal.
2. Recursive Backtracking (solveNQueensUtil):
○ Attempts to place queens column by column.
○ Backtracks if placing a queen leads to a conflict.
3. Print Solution:
○ Outputs the board configuration where queens (Q) are placed.

Sample Output (for N = 8):


css
Copy code
Q . . . . . . .
. . . Q . . . .
. . . . . Q . .
. . . . . . . Q
. Q . . . . . .
. . . . Q . . .
. . Q . . . . .
. . . . . . Q .

You can modify the value of N to solve for different sizes of chessboards!

Q5(a): Adjacency Matrix Analysis for a Directed Graph

Given Tasks:

1. Count the number of edges in the graph.


2. Check if there's a node not connected to any other node.
3. Check if there's a node with no outgoing edge.
4. Check if there's a node with no incoming edge.
5. Check if a node is connected to all other nodes.
6. Find the maximum degree (total in-degree + out-degree).

C++ Code:
cpp
Copy code
#include <iostream>
using namespace std;

#define MAX 100 // Maximum number of nodes

void analyzeGraph(int graph[MAX][MAX], int n) {


int totalEdges = 0;
int maxDegree = 0;
for (int i = 0; i < n; i++) {
int inDegree = 0, outDegree = 0;
bool connected = false;

for (int j = 0; j < n; j++) {


// Count edges
if (graph[i][j] == 1) {
totalEdges++;
outDegree++;
connected = true;
}
if (graph[j][i] == 1) {
inDegree++;
}
}

// Check for nodes with no incoming or outgoing edges


if (inDegree == 0) cout << "Node " << i << " has no incoming
edges.\n";
if (outDegree == 0) cout << "Node " << i << " has no outgoing
edges.\n";
if (!connected) cout << "Node " << i << " is isolated (not
connected).\n";

// Update maximum degree


maxDegree = max(maxDegree, inDegree + outDegree);
}

cout << "Total edges in the graph: " << totalEdges << endl;
cout << "Maximum degree of any node: " << maxDegree << endl;
}

int main() {
int n = 4; // Number of nodes
int graph[MAX][MAX] = {
{0, 1, 0, 0},
{0, 0, 1, 1},
{0, 0, 0, 1},
{0, 0, 0, 0}
};

analyzeGraph(graph, n);

return 0;
}

Q5(b): Depth First Search (DFS) and Breadth First Search (BFS)

Explanation:

● DFS uses a stack (or recursion) to explore as deep as possible before backtracking.
● BFS uses a queue to explore all neighbors of a node level by level.

C++ Code:
cpp
Copy code
#include <iostream>
#include <queue>
#include <stack>
using namespace std;

#define MAX 100

void DFS(int graph[MAX][MAX], int n, int start) {


bool visited[MAX] = {false};
stack<int> s;
s.push(start);

cout << "DFS Traversal: ";


while (!s.empty()) {
int node = s.top();
s.pop();

if (!visited[node]) {
visited[node] = true;
cout << node << " ";

for (int i = n - 1; i >= 0; i--) { // Explore neighbors


if (graph[node][i] == 1 && !visited[i]) {
s.push(i);
}
}
}
}
cout << endl;
}

void BFS(int graph[MAX][MAX], int n, int start) {


bool visited[MAX] = {false};
queue<int> q;
q.push(start);
visited[start] = true;

cout << "BFS Traversal: ";


while (!q.empty()) {
int node = q.front();
q.pop();
cout << node << " ";

for (int i = 0; i < n; i++) {


if (graph[node][i] == 1 && !visited[i]) {
visited[i] = true;
q.push(i);
}
}
}
cout << endl;
}

int main() {
int n = 4; // Number of nodes
int graph[MAX][MAX] = {
{0, 1, 1, 0},
{0, 0, 1, 1},
{0, 0, 0, 1},
{0, 0, 0, 0}
};

DFS(graph, n, 0);
BFS(graph, n, 0);

return 0;
}

Q5(c): Adjacency List Representation from Edge List

Input:

Edge list representation like {{a, b}, {b, c}, {a, c}}.

Output:

Adjacency list for the graph.

C++ Code:
cpp
Copy code
#include <iostream>
using namespace std;

#define MAX 100

void edgeListToAdjList(int edges[][2], int edgeCount, int


adjList[MAX][MAX], int n) {
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
adjList[i][j] = 0; // Initialize adjacency list
}
}

for (int i = 0; i < edgeCount; i++) {


int u = edges[i][0];
int v = edges[i][1];
adjList[u][v] = 1; // Add edge u -> v
adjList[v][u] = 1; // Add edge v -> u (undirected)
}
}

void printAdjList(int adjList[MAX][MAX], int n) {


for (int i = 0; i < n; i++) {
cout << "Node " << i << ": ";
for (int j = 0; j < n; j++) {
if (adjList[i][j]) cout << j << " ";
}
cout << endl;
}
}

int main() {
int edges[][2] = {
{0, 1}, {1, 2}, {0, 2}
};
int edgeCount = 3;
int n = 3; // Number of nodes

int adjList[MAX][MAX];
edgeListToAdjList(edges, edgeCount, adjList, n);
printAdjList(adjList, n);

return 0;
}
(a) Adjacency Matrix, Incidence Matrix, and Adjacency List Comparison

1. Adjacency Matrix:
○ A 2D matrix of size N×NN \times NN×N, where NNN is the number of vertices.
○ Entry adj[i][j]=1adj[i][j] = 1adj[i][j]=1 if there's an edge from vertex iii to jjj;
otherwise 000.
○ Memory Required: O(N2)O(N^2)O(N2).
2. Incidence Matrix:
○ A 2D matrix of size N×MN \times MN×M, where MMM is the number of edges.
○ Entry inc[i][j]=1inc[i][j] = 1inc[i][j]=1 if vertex iii is connected to edge jjj.
○ Memory Required: O(N×M)O(N \times M)O(N×M).
3. Adjacency List:
○ An array of lists where each index represents a vertex, and the list contains all
adjacent vertices.
○ Memory Required: O(N+M)O(N + M)O(N+M), since storing edges is
proportional to the number of edges MMM, and vertices NNN.

(b) Traversal Methods and BFS Algorithm

Traversal Methods:

● Breadth-First Search (BFS): Explores all neighbors level by level.


● Depth-First Search (DFS): Explores as far as possible along each branch before
backtracking.

C++ Code for BFS using array:

#include <iostream>

#include <queue>

using namespace std;

void BFS(int start, int adjMatrix[6][6], int n) {

bool visited[6] = {false};

queue<int> q;

visited[start] = true;
q.push(start);

cout << "BFS Traversal: ";

while (!q.empty()) {

int node = q.front();

q.pop();

cout << char(node + 'a') << " "; // Convert to letter representation

for (int i = 0; i < n; ++i) {

if (adjMatrix[node][i] != 0 && !visited[i]) {

visited[i] = true;

q.push(i);

cout << endl;

int main() {

int adjMatrix[6][6] = {

{0, 1, 0, 0, 0, 0},

{1, 0, 6, 8, 0, 2},

{0, 6, 0, 7, 0, 0},

{0, 8, 7, 0, 9, 2},
{0, 0, 0, 9, 0, 1},

{0, 2, 0, 2, 1, 0}

};

BFS(0, adjMatrix, 6); // Start BFS from node 'a' (index 0)

return 0;

(c) Shortest Path Using Dijkstra's Algorithm (with adjacency matrix and
arrays)

C++ Code:

cpp

Copy code

#include <iostream>

#include <climits>

using namespace std;

void dijkstra(int graph[6][6], int source, int n) {

int dist[6]; // Distance array

bool visited[6]; // Visited array

// Initialize distances and visited status

for (int i = 0; i < n; ++i) {

dist[i] = INT_MAX;
visited[i] = false;

dist[source] = 0; // Distance to itself is 0

// Main Dijkstra's algorithm loop

for (int count = 0; count < n - 1; ++count) {

// Find the vertex with the smallest distance

int minDist = INT_MAX, u = -1;

for (int i = 0; i < n; ++i) {

if (!visited[i] && dist[i] < minDist) {

minDist = dist[i];

u = i;

visited[u] = true;

// Update distances of neighbors

for (int v = 0; v < n; ++v) {

if (!visited[v] && graph[u][v] && dist[u] != INT_MAX &&


dist[u] + graph[u][v] < dist[v]) {

dist[v] = dist[u] + graph[u][v];

}
}

// Print the results

cout << "Shortest paths from node " << char(source + 'a') <<
":\n";

for (int i = 0; i < n; ++i) {

cout << "To node " << char(i + 'a') << " -> " << (dist[i] ==
INT_MAX ? -1 : dist[i]) << "\n";

int main() {

int graph[6][6] = {

{0, 1, INT_MAX, INT_MAX, INT_MAX, INT_MAX},

{1, 0, 6, 8, INT_MAX, 2},

{INT_MAX, 6, 0, 7, INT_MAX, INT_MAX},

{INT_MAX, 8, 7, 0, 9, 2},

{INT_MAX, INT_MAX, INT_MAX, 9, 0, 1},

{INT_MAX, 2, INT_MAX, 2, 1, 0}

};

dijkstra(graph, 0, 6); // Source node 'a' (index 0)


return 0;

Explanation:

1. BFS Implementation:
○ Uses an adjacency matrix (adjMatrix) of size n×nn \times nn×n and a queue
for traversal.
○ A visited array ensures each node is processed only once.
2. Dijkstra’s Algorithm:
○ Uses arrays for dist (distance from source) and visited (to mark processed
nodes).
○ For each node, it finds the minimum distance unvisited node and updates the
distances of its neighbors.

You might also like