Task 8 Minimum Spanning Tree using Kruskal’s Algorithm
Aim:
Create a C program to find Minimum Cost Spanning Tree of a given undirected graph using
Kruskal’s algorithm
Algorithm:
Step 1 : Create a graph where all edges are connected.
Step 2 : Sort all the edges from low weight to high
Step 3: Take the edge with the lowest weight and add it to the spanning tree
Step 4 : If adding the edge created the cycle then reject that edge
Step 4 : Keep adding the edges until we reach all vertices
Program:
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
int i, j, k, a, b, u, v, n, ne = 1;
int min, mincost = 0, cost[9][9], parent[9];
int find(int);
int uni(int, int);
void main() {
printf("\n\tImplementation of Kruskal's Algorithm\n");
printf("\nEnter the no. of vertices:");
scanf("%d", & n);
printf("\nEnter the cost adjacency matrix:\n");
for (i = 1; i <= n; i++) {
for (j = 1; j <= n; j++) {
scanf("%d", & cost[i][j]);
if (cost[i][j] == 0)
cost[i][j] = 999;
}
}
printf("The edges of Minimum Cost Spanning Tree are\n");
while (ne < n) {
for (i = 1, min = 999; i <= n; i++) {
for (j = 1; j <= n; j++) {
if (cost[i][j] < min) {
min = cost[i][j];
a = u = i;
b = v = j;
}
}
}
u = find(u);
v = find(v);
if (uni(u, v)) {
printf("%d edge (%d,%d) =%d\n", ne++, a, b, min);
mincost += min;
}
cost[a][b] = cost[b][a] = 999;
}
printf("\n\tMinimum cost = %d\n", mincost);
getch();
}
int find(int i) {
while (parent[i])
i = parent[i];
return i;
}
int uni(int i, int j) {
if (i != j) {
parent[j] = i;
return 1;
}
return 0;
}
OUTPUT:
Enter the no. of vertices:3
Enter the cost adjacency matrix:
9
8
7
6
5
4
3
2
3
The edges of Minimum Cost Spanning Tree are
1 edge (3,2) =2
2 edge (3,1) =3
Minimum cost = 5
TestCase 1: Assume an input graph with more than one edge having a same weight, in such case
which edge should be selected as the next visiting vertex by applying Kruskal’s algorithm.
Algorithm:
Step 1 : Create a graph where all edges are connected.
Step 2 : Sort all the edges from low weight to high
Step 3: Take the edge with the lowest weight and add it to the spanning tree
Step 4 : If adding the edge created the cycle then reject that edge
Step 4 : Keep adding the edges until we reach all vertices
Program:
#include <stdio.h>
#define MAX 30
typedef struct edge {
int u, v, w;
} edge;
typedef struct edge_list {
edge data[MAX];
int n;
} edge_list;
edge_list elist;
int Graph[MAX][MAX], n;
edge_list spanlist;
void kruskalAlgo();
int find(int belongs[], int vertexno);
void applyUnion(int belongs[], int c1, int c2);
void sort();
void print();
// Applying Krushkal Algo
void kruskalAlgo() {
int belongs[MAX], i, j, cno1, cno2;
elist.n = 0;
for (i = 1; i < n; i++)
for (j = 0; j < i; j++) {
if (Graph[i][j] != 0) {
[Link][elist.n].u = i;
[Link][elist.n].v = j;
[Link][elist.n].w = Graph[i][j];
elist.n++;
}
}
sort();
for (i = 0; i < n; i++)
belongs[i] = i;
spanlist.n = 0;
for (i = 0; i < elist.n; i++) {
cno1 = find(belongs, [Link][i].u);
cno2 = find(belongs, [Link][i].v);
if (cno1 != cno2) {
[Link][spanlist.n] = [Link][i];
spanlist.n = spanlist.n + 1;
applyUnion(belongs, cno1, cno2);
}
}
}
int find(int belongs[], int vertexno) {
return (belongs[vertexno]);
}
void applyUnion(int belongs[], int c1, int c2) {
int i;
for (i = 0; i < n; i++)
if (belongs[i] == c2)
belongs[i] = c1;
}
// Sorting algo
void sort() {
int i, j;
edge temp;
for (i = 1; i < elist.n; i++)
for (j = 0; j < elist.n - 1; j++)
if ([Link][j].w > [Link][j + 1].w) {
temp = [Link][j];
[Link][j] = [Link][j + 1];
[Link][j + 1] = temp;
}
}
// Printing the result
void print() {
int i, cost = 0;
for (i = 0; i < spanlist.n; i++) {
printf("\n%d - %d : %d", [Link][i].u, [Link][i].v, [Link][i].w);
cost = cost + [Link][i].w;
}
printf("\nSpanning tree cost: %d", cost);
}
int main() {
int i, j, total_cost;
n = 6;
Graph[0][0] = 0;
Graph[0][1] = 4;
Graph[0][2] = 4;
Graph[0][3] = 0;
Graph[0][4] = 0;
Graph[0][5] = 0;
Graph[0][6] = 0;
Graph[1][0] = 4;
Graph[1][1] = 0;
Graph[1][2] = 2;
Graph[1][3] = 0;
Graph[1][4] = 0;
Graph[1][5] = 0;
Graph[1][6] = 0;
Graph[2][0] = 4;
Graph[2][1] = 2;
Graph[2][2] = 0;
Graph[2][3] = 3;
Graph[2][4] = 4;
Graph[2][5] = 0;
Graph[2][6] = 0;
Graph[3][0] = 0;
Graph[3][1] = 0;
Graph[3][2] = 3;
Graph[3][3] = 0;
Graph[3][4] = 3;
Graph[3][5] = 0;
Graph[3][6] = 0;
Graph[4][0] = 0;
Graph[4][1] = 0;
Graph[4][2] = 4;
Graph[4][3] = 3;
Graph[4][4] = 0;
Graph[4][5] = 0;
Graph[4][6] = 0;
Graph[5][0] = 0;
Graph[5][1] = 0;
Graph[5][2] = 2;
Graph[5][3] = 0;
Graph[5][4] = 3;
Graph[5][5] = 0;
Graph[5][6] = 0;
kruskalAlgo();
print();
}
Output:
Solution 1:
2-1:2
5-2:2
3-2:3
4-3:3
1-0:4
Spanning tree cost: 14
Test Case 2: Construct a Maximum Spanning tree for the input graph by applying Kruskal’s
algorithm.
Algorithm:
Algorithm:
Step 1 : Create a graph where all edges are connected.
Step 2 : Sort all the edges from high weight to low
Step 3: Take the edge with the highestt weight and add it to the spanning tree
Step 4 : If adding the edge created the cycle then reject that edge
Step 4 : Keep adding the edges until we reach all vertices
Program:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_EDGES 25000
#define MAX_NODES 1000
typedef struct {
int u, v, w;
} Edge;
int n, m;
Edge edges[MAX_EDGES];
int parent[MAX_NODES];
int cmp(const void *a, const void *b) {
Edge *x = (Edge *)a, *y = (Edge *)b;
return y->w - x->w;
}
int find(int x) {
if (parent[x] == x)
return x;
return parent[x] = find(parent[x]);
}
void kruskal() {
int i, u, v, cost = 0;
qsort(edges, m, sizeof(Edge), cmp);
for (i = 1; i <= n; i++)
parent[i] = i;
for (i = 0; i < m; i++) {
u = find(edges[i].u), v = find(edges[i].v);
if (u != v) {
parent[u] = v;
cost += edges[i].w;
}
}
printf("The maximum spanning tree has a cost of %d.\n", cost);
}
int main() {
int i;
printf("Enter the number of nodes and edges: ");
scanf("%d %d", &n, &m);
printf("Enter the edges (u v w):\n");
for (i = 0; i < m; i++)
scanf("%d %d %d", &edges[i].u, &edges[i].v, &edges[i].w);
kruskal();
return 0;
}
OUTPUT:
Enter the number of nodes and edges: 3 3
Enter the edges (u v w):
125
238
137
The maximum spanning tree has a cost of 15.
Task 9: Greedy Technique – Dijkstra’s algorithm
Aim:
Create to c program to find shortest path using dijkstra’s algorithm
Algorithm:
Step 1 : Create a set shortPath to store vertices that come in the way of the shortest path tree.
Step 2 : Initialize all distance values as INFINITE and assign distance values as 0 for source
vertex so that it is picked first.
Step 3 : Loop until all vertices of the graph are in the shortPath.
Step 4 : Take a new vertex that is not visited and is nearest.
Step 5 : Add this vertex to shortPath.
Step 6 : For all adjacent vertices of this vertex update distances. Now check every adjacent
vertex of V, if sum of distance of u and weight of edge is less the update it
Program:
#include<stdio.h>
#include<conio.h>
#include<process.h>
#include<string.h>
#include<math.h>
#define IN 99
#define N 6
int dijkstra(int cost[][N], int source, int target);
int main()
{
int cost[N][N],i,j,w,ch,co;
int source, target,x,y;
printf("\t The Shortest Path Algorithm ( DIJKSTRA'S ALGORITHM in C \n\n");
for(i=1;i< N;i++)
for(j=1;j< N;j++)
cost[i][j] = IN;
for(x=1;x< N;x++)
{
for(y=x+1;y< N;y++)
{
printf("Enter the weight of the path between nodes %d and %d: ",x,y);
scanf("%d",&w);
if(w<0)
{
printf("Dijkstra’s Algorithm cannot work for a weighted connected graph
with negative weights.");
exit(0);
}
else
cost [x][y] = cost[y][x] = w;
}
printf("\n");
}
printf("\nEnter the source:");
scanf("%d", &source);
printf("\nEnter the target");
scanf("%d", &target);
co = dijsktra(cost,source,target);
printf("\nThe Shortest Path: %d",co);
}
int dijsktra(int cost[][N],int source,int target)
{
int dist[N],prev[N],selected[N]={0},i,m,min,start,d,j;
char path[N];
for(i=1;i< N;i++)
{
dist[i] = IN;
prev[i] = -1;
}
start = source;
selected[start]=1;
dist[start] = 0;
while(selected[target] ==0)
{
min = IN;
m = 0;
for(i=1;i< N;i++)
{
d = dist[start] +cost[start][i];
if(d< dist[i]&&selected[i]==0)
{
dist[i] = d;
prev[i] = start;
}
if(min>dist[i] && selected[i]==0)
{
min = dist[i];
m = i;
}
}
start = m;
selected[start] = 1;
}
start = target;
j = 0;
while(start != -1)
{
path[j++] = start+65;
start = prev[start];
}
path[j]='\0';
strrev(path);
printf("%s", path);
return dist[target];
}
Sample Input/output:
Test case 1:
Enter no. of vertices:4
Enter the adjacency matrix:
0120
1070
2703
0030
Enter the starting node:0
Distance of node1=1
Path=1<-0
Distance of node2=2
Path=2<-0
Distance of node3=5
Path=3<-2<-0
Testcase 2:
Enter no. of vertices:3
Enter the adjacency matrix:
0 1 -1
101
-1 1 0
Enter the starting node:0
Dijkstra’s Algorithm cannot work for a weighted connected graph with negative weights
Result:
Thus the dijikstra’s algorithm was executed successfully.
Task 10-Greedy Technique – Topological Sort
Aim:
Implement a c program for topological ordering
Algorithm:
Step 1:Store each vertex’s In-Degree in an array D
Step 2. Initialize queue with all “in-degree=0” vertices
Step 3. While there are vertices remaining in the queue:
(a) Dequeue and output a vertex
(b) Reduce In-Degree of all vertices adjacent to it by 1
(c) Enqueue any of these vertices whose In-Degree became zero
Step 4. If all vertices are output then success, otherwise there is a cycle.
Program:
#include<stdio.h>
#include<stdlib.h>
#define MAX 100
int n;
int adj[MAX][MAX];
void create_graph();
int queue[MAX], front = -1,rear = -1;
void insert_queue(int v);
int delete_queue();
int isEmpty_queue();
int indegree(int v);
int main()
{
int i,v,count,topo_order[MAX],indeg[MAX];
create_graph();
for(i=0;i<n;i++)
{
indeg[i] = indegree(i);
if( indeg[i] == 0 )
insert_queue(i);
}
count = 0;
while( !isEmpty_queue( ) && count < n )
{
v = delete_queue();
topo_order[++count] = v;
for(i=0; i<n; i++)
{
if(adj[v][i] == 1)
{
adj[v][i] = 0;
indeg[i] = indeg[i]-1;
if(indeg[i] == 0)
insert_queue(i);
}
}
}
if( count < n )
{
printf("\nNo topological ordering possible, graph contains cycle\n");
exit(1);
}
printf("\nVertices in topological order are :\n");
for(i=1; i<=count; i++)
printf( "%d ",topo_order[i] );
printf("\n");
return 0;
}
void insert_queue(int vertex)
{
if (rear == MAX-1)
printf("\nQueue Overflow\n");
else
{
if (front == -1) /*If queue is initially empty */
front = 0;
rear = rear+1;
queue[rear] = vertex ;
}
}
int isEmpty_queue()
{
if(front == -1 || front > rear )
return 1;
else
return 0;
}
int delete_queue()
{
int del_item;
if (front == -1 || front > rear)
{
printf("\nQueue Underflow\n");
exit(1);
}
else
{
del_item = queue[front];
front = front+1;
return del_item;
}
}
int indegree(int v)
{
int i,in_deg = 0;
for(i=0; i<n; i++)
if(adj[i][v] == 1)
in_deg++;
return in_deg;
}
void create_graph()
{
int i,max_edges,origin,destin;
printf("\nEnter number of vertices : ");
scanf("%d",&n);
max_edges = n*(n-1);
for(i=1; i<=max_edges; i++)
{
printf("\nEnter edge %d(-1 -1 to quit): ",i);
scanf("%d %d",&origin,&destin);
if((origin == -1) && (destin == -1))
break;
if( origin >= n || destin >= n || origin<0 || destin<0)
{
printf("\nInvalid edge!\n");
i--;
}
else
adj[origin][destin] = 1;
}
}
Sample Input/Output:
Testcase 1:
Enter number of vertices : 4
Enter edge 1(-1 -1 to quit): 01
Enter edge 2(-1 -1 to quit): 02
Enter edge 3(-1 -1 to quit): 23
Enter edge 4(-1 -1 to quit): -1-1
Vertices in topological order are :0 1 2 3
Result:
Thus the c program for topological ordering was executed.