Assignment 4[1]
Assignment 4[1]
Constraints:
• Each city must be connected to the road network.
• The road network must form a tree structure without any cycles.
• The total cost of road construction must be minimized.
• The road construction budget is limited.
• The distances between cities represent the weights of the edges in the
graph.
A-4.2. You are a delivery coordinator for an e-commerce company,
responsible for dispatching packages to customers within a city. The city is
represented as a graph, where each intersection is a node, and each road
between intersections is an edge. Your task is to develop an algorithm to
find the shortest route for delivering all packages, starting from the
company's warehouse and returning to the warehouse after all deliveries are
made.
Constraints:
• The city graph is undirected and connected that is given above.
• Each intersection can have multiple outgoing roads leading to other
intersections.
• Each package has a specific delivery address (intersection).
• The delivery person begins at the warehouse and must return to the
warehouse after delivering all packages.
• The objective is to minimize the total distance travelled by the delivery
person.
• Only one package can be carried at a time.
• Each package must be delivered to its designated address.
A-4.1 Algorithm:
minKey Function
1. Set min to a very large number (INT_MAX):
• This is used to keep track of the smallest key value found so far.
2. Set min_index to -1:
• This will hold the index of the city with the smallest key value.
3. Loop through all vertices (cities) from 0 to V-1:
• for (int v = 0; v < V; v++)
4. Inside the loop, check:
• If mstSet[v] == 0 → the city is not yet included in MST
• AND key[v] < min → the key (distance) is smaller than the
current min
5. If both conditions are true:
• Update min = key[v]
• Update min_index = v
→ This means we found a better (closer) unconnected city.
6. After the loop ends, return min_index:
• This gives the index of the city that is closest and not yet
connected.
primMST Function
1. Create three arrays:
• parent[]: Keeps track of the parent city for each city in the MST.
• key[]: Stores the minimum cost to connect each city to the MST
(start with infinity for all cities).
• mstSet[]: Tracks which cities are already connected to the MST
(all false at the start).
2. Initialize the arrays:
• Set key[] for all cities to infinity (∞), except key[0] = 0 (since we
start from city 0).
• Set mstSet[] for all cities to false (no cities are connected at the
beginning).
• Set parent[0] = -1 (city 0 has no parent since it's the first city).
3. Repeat V-1 times (because we need to connect V-1 edges):
• Find the city with the smallest key that is not yet connected
using the minKey() function.
o u = minKey(key, mstSet)
• Mark the city as connected:
o mstSet[u] = true (Now city u is included in the MST).
4. Look at each neighboring city:
• For each city v:
o If there is a road between city u and v (graph[u][v] != 0),
and:
o City v is not connected (mstSet[v] == false), and
o The road between u and v is shorter than the current key
for city v (graph[u][v] < key[v]):
▪ Update parent[v] to city u (this means city v is now
connected to city u).
▪ Update key[v] to the cost of the road between u and
v.
5. After the loop ends (all cities are connected):
• Print the MST by looking at the parent[] array.
o Each parent[i] tells us which city is connected to city i in
the MST.
• Calculate the total weight of the MST:
o Sum up all the roads used (from graph[u][v]).
A-4.1 Source Code:
#include <stdio.h>
#include <limits.h>
#define V 8
int minKey(int key[], int mstSet[]) {
int min = INT_MAX, min_index;
for (int v = 0; v < V; v++)
if (!mstSet[v] && key[v] < min) min = key[v], min_index = v;
return min_index;
}
void primMST(int graph[V][V]) {
int parent[V], key[V], mstSet[V] = {0}, totalWeight = 0;
for (int i = 0; i < V; i++) key[i] = INT_MAX;
key[0] = 0, parent[0] = -1;
primMST(graph);
return 0;
}
A-4.1 Input/Output:
A-4.1 Analysis:
1. Time Complexity Analysis:
•Finding the minimum key vertex (in minKey()):
• Scans all vertices to find the minimum key[v] not yet
included in MST.
• Time per call: O(V)
• Called V times → total: O(V²)
•Updating adjacent vertices in the main loop of primMST() :
• For each of the V vertices, the inner loop checks all V possible
adjacent vertices.
• In the worst case (dense graph), this results in O(V²) total
operations.
Find Function
• Call FIND on i's parent to keep going up until you find the
leader.
• While you're doing this, update i's parent directly to the leader
(this is called path compression — it makes future lookups
faster).
union_sets Function
1. Find roots of x and y:
• xroot = find(x)
• yroot = find(y)
• This gets the root representative of the sets that x and y belong
to.
2. Compare their ranks:
• IF rank[xroot] < rank[yroot]
• Attach the tree with smaller rank to the root of the larger
rank tree.
• This helps keep the tree shallow → faster future lookups.
3. Merge accordingly:
• If xroot's rank is less, attach it under yroot.
• If yroot's rank is less, attach it under xroot.
• If they are equal, attach one to the other and increase the
rank of the new root.
Merge Sort:
4. Divide:
• If the array (or sub-array) has more than 1 element:
o Find the middle point: mid = (left + right) / 2
o Recursively call mergeSort() on the left half
o Recursively call mergeSort() on the **right half`
• Keep dividing until each part has only one element (which is
already "sorted").
5. Conquer (Merge):
• Once divided into single elements, start merging back:
• Compare elements from two parts.
• Put them together in sorted order.
• Use the merge() function to do this.
Merge Function
1. Split the array into two halves:
• Left half: from left to mid
• Right half: from mid + 1 to right
2. Copy those two halves into two new temporary arrays: L[] and
R[].
3. Compare elements from both arrays:
• If L[i].weight is smaller or equal, take from L
• Otherwise, take from R
• Put the chosen element back into the main array arr[k]
4. Copy any leftovers from L[] or R[] into arr[].
kruskalMST Function
1. Create Edge List:
• Loop through the graph matrix.
• For every connection graph[i][j] that’s not 0, make an edge
(i, j, weight).
• Store all these edges in an edge_list[].
3. Sort Edges:
• Sort all edges in increasing order of weight using
mergeSort().
6. Print Result:
• Show the total weight of the Minimum Spanning Tree.
A-4.2 Source Code:
#include <stdio.h>
#include <limits.h>
#define V 8
typedef struct {
int src, dest, weight;
} Edge;
int find(int i) {
if (parent[i] == i) return i;
return parent[i] = find(parent[i]);
}
void union_sets(int x, int y) {
int xroot = find(x);
int yroot = find(y);
if (rank[xroot] < rank[yroot]) parent[xroot] = yroot;
else if (rank[xroot] > rank[yroot]) parent[yroot] = xroot;
else {
parent[yroot] = xroot;
rank[xroot]++;
}
}
void merge(Edge arr[], int left, int mid, int right) {
int n1 = mid - left + 1;
int n2 = right - mid;
Edge L[n1], R[n2];
int i = 0, j = 0, k = left;
while (i < n1 && j < n2) {
if (L[i].weight <= R[j].weight) arr[k++] = L[i++];
else arr[k++] = R[j++];
}
while (i < n1) arr[k++] = L[i++];
while (j < n2) arr[k++] = R[j++];
}
void mergeSort(Edge arr[], int left, int right) {
if (left < right) {
int mid = left + (right - left) / 2;
mergeSort(arr, left, mid);
mergeSort(arr, mid + 1, right);
merge(arr, left, mid, right);
}
}
void kruskalMST(int graph[V][V]) {
Edge edges[V * (V - 1) / 2];
int e = 0;
for (int i = 0; i < V; i++)
for (int j = i + 1; j < V; j++)
if (graph[i][j] != 0) {
edges[e].src = i;
edges[e].dest = j;
edges[e].weight = graph[i][j];
e++;
}
for (int i = 0; i < V; i++) {
parent[i] = i;
rank[i] = 0;
}
mergeSort(edges, 0, e - 1);
printf("Sorted Edges by Weight:\n");
for (int i = 0; i < e; i++) {
printf("C%d - C%d\tWeight: %d\n", edges[i].src + 1, edges[i].dest + 1,
edges[i].weight);
}
int mst_weight = 0;
int edge_count = 0;
printf("\nEdges in MST (Path) and Weights:\n");
for (int i = 0; i < e; i++) {
int u = edges[i].src;
int v = edges[i].dest;
int set_u = find(u);
int set_v = find(v);
if (set_u != set_v) {
printf("C%d - C%d\tWeight: %d\n", u + 1, v + 1, edges[i].weight);
mst_weight += edges[i].weight;
union_sets(set_u, set_v);
edge_count++;
if (edge_count == V - 1) break;
}
}
printf("\nTotal Weight of MST: %d\n", mst_weight);
}
int main() {
int graph[V][V] = {
{0, 40, 60, 45, 0, 0, 0, 0},
{40, 0, 0, 30, 100, 0, 0, 0},
{60, 0, 0, 40, 0, 0, 80, 70},
{45, 30, 40, 0, 60, 0, 50, 0},
{0, 100, 0, 60, 0, 50, 30, 0},
{0, 0, 0, 0, 50, 0, 30, 70},
{0, 0, 80, 50, 30, 30, 0, 40},
{0, 0, 70, 0, 0, 70, 40, 0}
};
kruskalMST(graph);
return 0;
}
A-4.2 Input/Output:
A-4.2 Analysis:
1. Time Complexity Analysis:
• Collecting all the edges from the graph
o This checks all possible pairs of cities (nodes).
o Time: Takes about V² time if there are many roads (dense
graph).
• Sorting the edges by weight (distance or cost)
o Uses merge sort.
o Time: Takes E log E time, where E is the number of roads
(edges).
• Building the Minimum Spanning Tree (MST)
o Goes through the edges one by one, and checks if connecting
two cities forms a cycle or not.
o Time: Almost E time, but very fast because of how union-find
is used.
• Overall Time:
O(E log E)
This means, Sorting the edges is the slowest part, and that's what
mainly decides the total time.