Skip to content

Commit

Permalink
added mst problem #1599
Browse files Browse the repository at this point in the history
  • Loading branch information
SimranShaikh20 committed Nov 5, 2024
1 parent 36873e9 commit 022ca74
Show file tree
Hide file tree
Showing 2 changed files with 167 additions and 0 deletions.
54 changes: 54 additions & 0 deletions MinimumSpanningTree/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# Critical and Pseudo-Critical Edges in Minimum Spanning Tree

This repository contains a C implementation that identifies critical and pseudo-critical edges in a Minimum Spanning Tree (MST) of a given graph. The algorithm employs Kruskal's algorithm along with a disjoint set (union-find) data structure to efficiently manage the connected components of the graph.

## Table of Contents

- [Problem Description](#problem-description)
- [Definitions](#definitions)
- [Features](#features)
- [Input Format](#input-format)
- [Output Format](#output-format)
- [Example](#example)
- [How to Compile and Run](#how-to-compile-and-run)
- [Code Structure](#code-structure)
- [License](#license)
- [Acknowledgments](#acknowledgments)

## Problem Description

In a connected, undirected graph, edges play a crucial role in defining the structure of the Minimum Spanning Tree (MST). The MST is a subset of edges that connects all vertices with the minimum possible total edge weight. Understanding which edges are critical or pseudo-critical helps in network design and optimization.

## Definitions

- **Critical Edge**: An edge is considered critical if its removal increases the weight of the MST. This means that the MST cannot be formed without this edge.

- **Pseudo-Critical Edge**: An edge is considered pseudo-critical if it can be included in the MST without affecting the total weight, but removing it does not increase the MST weight. This means that while the edge is not essential for the MST, it can be part of it without changing the overall cost.

## Features

- **Efficient Edge Classification**: Uses Kruskal's algorithm to determine the MST and classify edges as critical or pseudo-critical.
- **Union-Find Structure**: Implements a disjoint set data structure to efficiently manage and merge connected components.
- **Dynamic Input Handling**: Accepts a variable number of edges and vertices, making it adaptable to different graph sizes.

## Input Format

The input consists of:
- An integer `n` representing the number of vertices in the graph.
- An integer `m` representing the number of edges in the graph.
- A 2D array `edges` where each element is an array containing three integers: the two vertices connected by the edge and the weight of the edge.

### Example Input

```c
int n = 5; // Number of vertices
int m = 7; // Number of edges
int edges[7][3] = {
{0, 1, 1}, // Edge from vertex 0 to vertex 1 with weight 1
{0, 2, 3}, // Edge from vertex 0 to vertex 2 with weight 3
{1, 2, 2}, // Edge from vertex 1 to vertex 2 with weight 2
{1, 3, 4}, // Edge from vertex 1 to vertex 3 with weight 4
{2, 3, 5}, // Edge from vertex 2 to vertex 3 with weight 5
{3, 4, 6}, // Edge from vertex 3 to vertex 4 with weight 6
{1, 4, 7} // Edge from vertex 1 to vertex 4 with weight 7
};
113 changes: 113 additions & 0 deletions MinimumSpanningTree/solution.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
#include <stdio.h>
#include <stdlib.h>

typedef struct {
int u, v, weight, index;
} Edge;

typedef struct {
int *parent;
int *rank;
int n;
} DisjointSet;

// Function to create a disjoint set
DisjointSet* createSet(int n) {
DisjointSet* ds = (DisjointSet*)malloc(sizeof(DisjointSet));
ds->parent = (int*)malloc(n * sizeof(int));
ds->rank = (int*)malloc(n * sizeof(int));
ds->n = n;
for (int i = 0; i < n; i++) {
ds->parent[i] = i;
ds->rank[i] = 0;
}
return ds;
}

// Find function with path compression
int find(DisjointSet* ds, int x) {
if (ds->parent[x] != x) {
ds->parent[x] = find(ds, ds->parent[x]);
}
return ds->parent[x];
}

// Union function by rank
void unionSets(DisjointSet* ds, int x, int y) {
int rootX = find(ds, x);
int rootY = find(ds, y);
if (rootX != rootY) {
if (ds->rank[rootX] > ds->rank[rootY]) {
ds->parent[rootY] = rootX;
} else if (ds->rank[rootX] < ds->rank[rootY]) {
ds->parent[rootX] = rootY;
} else {
ds->parent[rootY] = rootX;
ds->rank[rootX]++;
}
}
}

// Compare function for sorting edges
int compareEdges(const void* a, const void* b) {
return ((Edge*)a)->weight - ((Edge*)b)->weight;
}

// Function to calculate the weight of the MST
int kruskal(Edge* edges, int n, int m, int skipIndex, int includeIndex) {
DisjointSet* ds = createSet(n);
int weight = 0;
if (includeIndex != -1) {
unionSets(ds, edges[includeIndex].u, edges[includeIndex].v);
weight += edges[includeIndex].weight;
}
for (int i = 0; i < m; i++) {
if (i == skipIndex) continue;
if (find(ds, edges[i].u) != find(ds, edges[i].v)) {
unionSets(ds, edges[i].u, edges[i].v);
weight += edges[i].weight;
}
}
// Check if we formed a valid MST
int components = 0;
for (int i = 0; i < n; i++) {
if (ds->parent[i] == i) components++;
}
free(ds->parent);
free(ds->rank);
free(ds);
return components == 1 ? weight : -1; // Return -1 if not all nodes are connected
}

// Main function to find critical and pseudo-critical edges
void findCriticalAndPseudoCriticalEdges(int n, int m, int edges[][3], int* returnSize, int** returnArray) {
Edge* edgeList = (Edge*)malloc(m * sizeof(Edge));
for (int i = 0; i < m; i++) {
edgeList[i].u = edges[i][0];
edgeList[i].v = edges[i][1];
edgeList[i].weight = edges[i][2];
edgeList[i].index = i;
}

// Sort edges by weight
qsort(edgeList, m, sizeof(Edge), compareEdges);

// Find the weight of the MST without any edges removed
int mstWeight = kruskal(edgeList, n, m, -1, -1);

int* criticalEdges = (int*)malloc(m * sizeof(int));
int* pseudoCriticalEdges = (int*)malloc(m * sizeof(int));
int criticalCount = 0;
int pseudoCount = 0;

for (int i = 0; i < m; i++) {
// Check for critical edge
if (kruskal(edgeList, n, m, i, -1) > mstWeight) {
criticalEdges[criticalCount++] = edgeList[i].index;
} else if (kruskal(edgeList, n, m, -1, i) == mstWeight) {
// Check for pseudo-critical edge
pseudoCriticalEdges[pseudoCount++] = edgeList[i].index;
}
}

// Prepare

0 comments on commit 022ca74

Please sign in to comment.