Professional Documents
Culture Documents
ADA Manual-1
ADA Manual-1
1. C Program
2. Graphs, directed graph and undirected graphs
3. Minimum Cost Spanning Tree
4. Kruskal's algorithm
5. Prim's algorithm
18. find a subset of a given set S = {sl , s2,.....,sn} of n positive integers whose sum
is equal to a given positive integer d.
Directed Graph (Digraph): In a digraph, each edge has a direction, meaning it goes
from one vertex to another, indicated by an arrow.
Undirected Graph: In an undirected graph, edges have no direction, and they simply
connect two vertices.
Common Operations
Add Vertex: Add a new vertex to the graph.
Add Edge: Add a new edge between two vertices.
Remove Vertex: Remove a vertex and its associated edges.
Remove Edge: Remove an edge between two vertices.
Traverse: Visit all vertices and edges of the graph.
Properties
An MCST has n−1 edges for n vertices.
An MCST doesn't contain any cycles.
An MCST connects all vertices in a graph with the minimum total edge weight.
1. Design and implement C/C++ Program to find Minimum Cost Spanning Tree
of a given connected undirected graph using Kruskal's algorithm.
Kruskal's algorithm is a greedy algorithm used to find the Minimum Spanning Tree
(MST) of a connected, undirected graph. The algorithm grows a forest of trees by
adding the smallest edge that doesn't form a cycle until all vertices are connected.
Check Cycle:
If adding e to F doesn't form a cycle (i.e., the two vertices of e are in different trees),
add e to the MST T.
Update Forest:
Merge the two trees connected by e into one tree.
Termination:
When F forms a single tree, T is the MST.
Example
Let's consider a graph with vertices A,B,C,D,E and edges with weights as follows:
Termination:
T is the Minimum Spanning Tree with total weight = 1+1+2+3+4=11
Implementation in C
#include <stdio.h>
#include <stdlib.h>
// Function prototypes
int find(Subset subsets[], int i);
void Union(Subset subsets[], int x, int y);
void kruskalMST(Edge edges[], int V, int E);
kruskalMST(edges, V, E);
return 0;
}
// Free memory
free(subsets);
}
2. Design and implement C/C++ Program to find Minimum Cost Spanning Tree
of a given connected undirected graph using Prim's algorithm.
Prim's algorithm is a greedy algorithm used to find the Minimum Spanning Tree
(MST) of a connected, undirected graph. Unlike Kruskal's algorithm, which focuses
on edges, Prim's algorithm focuses on vertices. The algorithm grows a single tree (or
forest) by adding the closest vertex that is not already in the tree until all vertices are
included.
Initialization:
Select an arbitrary vertex v to start the MST.
Initialize an empty set S to store vertices included in the MST and a priority queue (or
min heap) to store edges.
Termination:
When S includes all vertices, the MST is complete.
Example
Let's consider a graph with vertices A,B,C,D,E and edges with weights as follows:
0 1 2 3 4
0 0 1 0 4 0
1 1 0 0 2 3
2 0 0 0 5 1
3 4 2 5 0 0
4 0 3 1 0 0
Vertex 0:
Connected to vertex 1 with weight 1
Connected to vertex 3 with weight 4
Vertex 1:
Connected to vertex 0 with weight 1
Connected to vertex 3 with weight 2
Connected to vertex 4 with weight 3
Vertex 2:
Connected to vertex 3 with weight 5
Connected to vertex 4 with weight 1
Vertex 3:
Connected to vertex 0 with weight 4
Connected to vertex 1 with weight 2
Connected to vertex 2 with weight 5
Vertex 4:
Connected to vertex 1 with weight 3
Connected to vertex 2 with weight 1
Implementation in C
#include <stdio.h>
#include <limits.h>
#define V 5
#define INF INT_MAX
int main() {
int graph[V][V] = {
{0, 1, 0, 4, 0},
{1, 0, 0, 2, 3},
{0, 0, 0, 5, 1},
{4, 2, 5, 0, 0},
{0, 3, 1, 0, 0}
};
primMST(graph);
return 0;
}
3. a. Design and implement C/C++ Program to solve All-Pairs Shortest Paths
problem using Floyd's algorithm.
b. Design and implement C/C++ Program to find the transitive closure using
Warshal's algorithm.
The All-Pairs Shortest Paths (APSP) problem is a classic problem in computer science
and graph theory. The goal of this problem is to find the shortest paths between every
pair of vertices in a weighted graph. The weights on the edges can represent distances,
costs, or any other metric, and can be both positive and negative.
There are several algorithms to solve the APSP problem, each with its own
advantages and disadvantages:
Floyd-Warshall Algorithm:
This is one of the most famous algorithms for solving the APSP problem.
It works for both directed and undirected graphs with positive or negative edge
weights.
The time complexity is O(V^3), where V is the number of vertices.
Johnson's Algorithm:
This algorithm is more efficient than Floyd-Warshall for sparse graphs (graphs with
relatively few edges).
It first transforms the edge weights using the Bellman-Ford algorithm to make them
non-negative, and then uses Dijkstra's algorithm for each vertex as the source.
The time complexity depends on the implementation, but it's generally better than
O(V^3) for sparse graphs.
The All-Pairs Shortest Paths (APSP) problem involves finding the shortest paths
between all pairs of vertices in a weighted graph. This problem is a generalization of
the Single-Source Shortest Path problem (like Dijkstra's or Bellman-Ford algorithms),
where the shortest path from a single source vertex to all other vertices is found.
Floyd's Algorithm:
Initialization: Create a distance matrix dist[][] where dist[i][j] stores the shortest
distance between vertex i and vertex j. Initialize dist[i][j] to the weight of the edge
between i and j if there is an edge, and to infinity otherwise. Also, initialize dist[i][i]
to 0.
Iterative Update: For each intermediate vertex k (from 1 to N, where N is the number
of vertices), update dist[i][j] as min(dist[i][j], dist[i][k] + dist[k][j]).
Edge weights:
Edge from 0 to 1: 1
Edge from 0 to 2: 2
Edge from 1 to 2: 1
Edge from 1 to 3: 3
Edge from 2 to 3: 2
Implementation:
/* Define Infinite as a large enough value. This value will be used for vertices not
connected to each other */
#define INF 99999
// Function call
floydWarshall(graph);
return 0;
}
Importance
Helps in determining if there exists a path between every pair of vertices.
Useful in applications like compilers (dead code elimination), databases (query
optimization), and network routing.
Warshall's Algorithm
Warshall's algorithm is a dynamic programming approach used to compute the
transitive closure of a given directed graph.
Algorithm Steps:
Initialization: Create a matrix reach[V][V] where V is the number of vertices in the
graph. Initialize this matrix with the adjacency matrix of the graph.
Transitive Closure Computation: For each vertex k (from 0 to V-1), update reach[i][j]
as reach[i][j] || (reach[i][k] && reach[k][j]).
Implemenatation
#include <stdio.h>
#include <stdbool.h>
#define V 4
int main() {
int graph[V][V] = {
{1, 1, 0, 0},
{0, 1, 1, 0},
{0, 0, 1, 1},
{0, 0, 0, 1}
};
transitiveClosure(graph);
return 0;
}
4. Design and implement C/C++ Program to find shortest paths from a given
vertex in a weighted connected graph to other vertices using Dijkstra's algorithm.
Algorithm Steps:
Initialization: Initialize a distance array dist[] to store the shortest distance from the
source vertex to each vertex. Initialize all distances as infinity (INT_MAX), except
for the source vertex which is 0.
Visited Set: Maintain a boolean array visited[] to mark vertices as visited or not.
Main Loop: Repeat the following steps until all vertices are visited:
Find the vertex u with the minimum distance dist[u] from the source vertex that has
not been visited yet.
Mark u as visited.
Update the distances of all adjacent vertices v of u if dist[u] + weight(u, v) < dist[v].
Example Problem
Given the following weighted graph, find the shortest paths from vertex 0 to all other
vertices using Dijkstra's algorithm:
Implementation
#include <stdio.h>
#include <stdbool.h>
#include <limits.h>
#define V 4
dist[src] = 0;
for (int count = 0; count < V - 1; count++) {
int u = minDistance(dist, visited);
visited[u] = true;
printSolution(dist);
}
int main() {
int graph[V][V] = {
{0, 10, 0, 1},
{10, 0, 5, 0},
{0, 0, 0, 3},
{1, 5, 3, 0}
};
dijkstra(graph, 0);
return 0;
}
5. Design and implement C/C++ Program to obtain the Topological ordering of
vertices in a given digraph.
Importance:
Topological ordering is commonly used in:
Task scheduling
Dependency resolution
Program compilation (for resolving dependencies between modules)
Kahn's Algorithm:
Use a queue to keep track of vertices with no incoming edges.
Remove vertices from the queue, update the incoming edges for its adjacent vertices,
and add them to the queue if they have no more incoming edges.
The vertices removed from the queue in the order they are removed form a valid
topological ordering.
Implementation
#include <stdio.h>
#include <stdlib.h>
struct Node {
int data;
struct Node* next;
};
struct Graph {
int numVertices;
struct Node** adjLists;
int* visited;
};
int main() {
int vertices = 6; // Number of vertices in the graph
struct Graph* graph = createGraph(vertices);
addEdge(graph, 5, 0);
addEdge(graph, 5, 2);
addEdge(graph, 4, 0);
addEdge(graph, 4, 2);
addEdge(graph, 2, 3);
addEdge(graph, 3, 1);
topologicalSort(graph);
return 0;
}