You are on page 1of 19

WEEK 7 solution

Q1:

#include <stdio.h>
#include <stdlib.h>
#include <limits.h>

#define V 6 // Number of vertices in the graph

// Function to find the vertex with minimum distance value, from the set of vertices not yet
included in shortest path tree
int minDistance(int dist[], int sptSet[]) {
int min = INT_MAX, min_index;

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


if (sptSet[v] == 0 && dist[v] <= min)
min = dist[v], min_index = v;

return min_index;
}

// Function to print the final shortest path from source vertex to all other vertices
void printSolution(int dist[]) {
printf("Vertex \t\t Distance from Source\n");
for (int i = 0; i < V; i++)
printf("%d \t\t %d\n", i, dist[i]);
}

// Function that implements Dijkstra's single source shortest path algorithm for a graph
represented using adjacency matrix representation
void dijkstra(int graph[V][V], int src) {
int dist[V]; // The output array. dist[i] will hold the shortest distance from src to i

int sptSet[V]; // sptSet[i] will be 1 if vertex i is included in shortest path tree or shortest distance
from src to i is finalized

// Initialize all distances as INFINITE and sptSet[] as 0


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

// Distance of source vertex from itself is always 0


dist[src] = 0;

// Find shortest path for all vertices


for (int count = 0; count < V - 1; count++) {
// Pick the minimum distance vertex from the set of vertices not yet processed.
int u = minDistance(dist, sptSet);

// Mark the picked vertex as processed


sptSet[u] = 1;
// Update dist value of the adjacent vertices of the picked vertex.
for (int v = 0; v < V; v++)
if (!sptSet[v] && graph[u][v] && dist[u] != INT_MAX && dist[u] + graph[u][v] < dist[v])
dist[v] = dist[u] + graph[u][v];
}

// print the constructed distance array


printSolution(dist);
}

int main() {
int graph[V][V] = { {0, 7, 9, 0, 0, 14},
{7, 0, 10, 15, 0, 0},
{9, 10, 0, 11, 0, 2},
{0, 15, 11, 0, 6, 0},
{0, 0, 0, 6, 0, 9},
{14, 0, 2, 0, 9, 0} };

dijkstra(graph, 0); // Run Dijkstra's Algorithm with source vertex 0

return 0;
}

Q2:

#include <stdio.h>
#include <stdlib.h>
#include <limits.h>

#define V 6 // Number of vertices in the graph

// Function to print the final shortest path from source vertex to all other vertices
void printSolution(int dist[]) {
printf("Vertex \t\t Distance from Source\n");
for (int i = 0; i < V; i++)
printf("%d \t\t %d\n", i, dist[i]);
}

// Function that implements Bellman-Ford algorithm for a graph represented using adjacency
matrix representation
void bellmanFord(int graph[V][V], int src) {
int dist[V]; // The output array. dist[i] will hold the shortest distance from src to i

// Initialize distances from src to all other vertices as INFINITE


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

// Relax all edges V-1 times. A simple shortest path from src to any other vertex can have at
most V-1 edges
for (int i = 0; i < V - 1; i++) {
for (int u = 0; u < V; u++) {
for (int v = 0; v < V; v++) {
if (graph[u][v] && dist[u] != INT_MAX && dist[u] + graph[u][v] < dist[v])
dist[v] = dist[u] + graph[u][v];
}
}
}

// Check for negative-weight cycles. If we get a shorter path, then there is a cycle
for (int u = 0; u < V; u++) {
for (int v = 0; v < V; v++) {
if (graph[u][v] && dist[u] != INT_MAX && dist[u] + graph[u][v] < dist[v]) {
printf("Graph contains negative-weight cycle\n");
return;
}
}
}

// print the constructed distance array


printSolution(dist);
}

int main() {

int graph[V][V] = { {0, 6, 0, 0, 7, 0},


{0, 0, 5, -4, 8, -2},
{0, -2, 0, 0, 0, 0},
{2, 0, 7, 0, 0, 0},
{0, -3, 9, 2, 0, 0},
{0, 0, 0, 0, -5, 0} };

bellmanFord(graph, 0); // Run Bellman-Ford Algorithm with source vertex 0

return 0;
}

Q3:

#include <stdio.h>
#include <stdlib.h>
#include <limits.h>

#define V 4 // Number of vertices in the graph

// Function to find the shortest path with exactly k edges from source to destination
int shortestPathWithKEdges(int graph[V][V], int src, int dest, int k) {
int dp[V][V][k+1]; // 3D array to store the shortest distance between each pair of vertices with k
edges on the path

// Initialize the 3D array with infinity for all pairs of vertices with k edges
for (int e = 0; e <= k; e++) {
for (int i = 0; i < V; i++) {
for (int j = 0; j < V; j++) {
dp[i][j][e] = INT_MAX;
}
}
}

// Initialize the 3D array with the weight of the direct edges between the vertices
for (int i = 0; i < V; i++) {
for (int j = 0; j < V; j++) {
if (graph[i][j] != 0) {
dp[i][j][1] = graph[i][j];
}
}
}

// Compute the shortest distance between each pair of vertices with exactly k edges on the
path
for (int e = 2; e <= k; e++) {
for (int i = 0; i < V; i++) {
for (int j = 0; j < V; j++) {
for (int x = 0; x < V; x++) {
if (graph[i][x] != 0 && dp[x][j][e-1] != INT_MAX) {
dp[i][j][e] = (dp[i][j][e] < dp[i][x][1] + dp[x][j][e-1]) ? dp[i][j][e] : (dp[i][x][1] + dp[x][j]
[e-1]);
}
}
}
}
}

// Return the shortest distance between the source and destination vertices with exactly k
edges on the path
return dp[src][dest][k];
}

int main() {
// The example graph from the assignment
int graph[V][V] = { {0, 10, 3, 0},
{0, 0, 0, 7},
{0, 0, 0, 6},
{0, 0, 0, 0} };

int src = 0; // Source vertex


int dest = 3; // Destination vertex
int k = 2; // Number of edges on the path

int shortestPath = shortestPathWithKEdges(graph, src, dest, k); // Find the weight of the
shortest path

if (shortestPath == INT_MAX) {
printf("There is no path with exactly %d edges from vertex %d to vertex %d\n", k, src, dest);
} else {
printf("The weight of the shortest path with exactly %d edges from vertex %d to vertex %d is
%d\n", k, src, dest, shortestPath);
}

return 0;
}

WEEK 8: Solution

Q1:

#include <stdio.h>
#include <stdbool.h>
#include <limits.h>

#define MAX_CITIES 100

int minimum_cost(int graph[MAX_CITIES][MAX_CITIES], int num_cities) {


bool visited[MAX_CITIES] = { false };
int MST[MAX_CITIES];
int start_city = 0; // Starting city (can be any)
int min_cost = 0;

visited[start_city] = true;
int edges[MAX_CITIES];
int num_edges = 0;

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


if (graph[start_city][i] != 0) {
edges[num_edges++] = i;
}
}

while (num_edges > 0) {


int min_cost_edge = INT_MAX;
int min_cost_dest = -1;

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


int dest = edges[i];

if (!visited[dest] && graph[start_city][dest] < min_cost_edge) {


min_cost_edge = graph[start_city][dest];
min_cost_dest = dest;
}
}
if (min_cost_dest != -1) {
visited[min_cost_dest] = true;
MST[min_cost_dest] = min_cost_edge;
min_cost += min_cost_edge;

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


if (graph[min_cost_dest][i] != 0 && !visited[i]) {
edges[num_edges++] = i;
}
}
}

num_edges--;
edges[min_cost_dest] = edges[num_edges];
}

return min_cost;
}

int main() {
int num_cities;
printf("Enter the number of cities: ");
scanf("%d", &num_cities);

int graph[MAX_CITIES][MAX_CITIES];
printf("Enter the adjacency matrix:\n");

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


for (int j = 0; j < num_cities; j++) {
scanf("%d", &graph[i][j]);
}
}

int min_cost = minimum_cost(graph, num_cities);


printf("Minimum cost: %d\n", min_cost);

return 0;
}

Q2:

#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>

#define MAX_CITIES 100

// Structure to represent an edge


struct Edge {
int src, dest, weight;
};
// Structure to represent a subset for union-find
struct Subset {
int parent;
int rank;
};

// Compare function used by qsort to sort edges based on weight


int compare(const void* a, const void* b) {
struct Edge* edge1 = (struct Edge*)a;
struct Edge* edge2 = (struct Edge*)b;
return edge1->weight - edge2->weight;
}

// Find the parent of a subset (with path compression)


int find(struct Subset subsets[], int i) {
if (subsets[i].parent != i)
subsets[i].parent = find(subsets, subsets[i].parent);
return subsets[i].parent;
}

// Union of two subsets (with union by rank)


void unionSets(struct Subset subsets[], int x, int

Q3:

#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>

#define MAX_VERTICES 100

struct Edge {
int src, dest, weight;
};

struct Subset {
int parent;
int rank;
};

int compare(const void* a, const void* b) {


struct Edge* edge1 = (struct Edge*)a;
struct Edge* edge2 = (struct Edge*)b;
return edge2->weight - edge1->weight;
}

int find(struct Subset subsets[], int i) {


if (subsets[i].parent != i)
subsets[i].parent = find(subsets, subsets[i].parent);
return subsets[i].parent;
}

void unionSets(struct Subset subsets[], int x, int y) {


int xroot = find(subsets, x);
int yroot = find(subsets, y);

if (subsets[xroot].rank < subsets[yroot].rank)


subsets[xroot].parent = yroot;
else if (subsets[xroot].rank > subsets[yroot].rank)
subsets[yroot].parent = xroot;
else {
subsets[yroot].parent = xroot;
subsets[xroot].rank++;
}
}

int maximum_budget(struct Edge edges[], int num_edges, int num_vertices) {


struct Subset* subsets = (struct Subset*)malloc(num_vertices * sizeof(struct Subset));
int max_spanning_weight = 0;

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


subsets[i].parent = i;
subsets[i].rank = 0;
}

qsort(edges, num_edges, sizeof(struct Edge), compare);

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


int src = edges[i].src;
int dest = edges[i].dest;
int src_parent = find(subsets, src);
int dest_parent = find(subsets, dest);

if (src_parent != dest_parent) {
max_spanning_weight += edges[i].weight;
unionSets(subsets, src_parent, dest_parent);
}
}

free(subsets);

return max_spanning_weight;
}

int main() {
int num_vertices;
printf("Enter the number of vertices in the graph: ");
scanf("%d", &num_vertices);

int num_edges = num_vertices * (num_vertices - 1) / 2;


struct Edge edges[num_edges];

int edge_index = 0;

printf("Enter the adjacency matrix:\n");


for (int i = 0; i < num_vertices; i++) {
for (int j = 0; j < i; j++) {
int weight;
scanf("%

WEEK 9: Solutions

Q1:

#include <stdio.h>
#include <stdbool.h>

#define INF 9999


#define MAX_VERTICES 100

void floyd_warshall(int graph[MAX_VERTICES][MAX_VERTICES], int num_vertices) {


int dist[MAX_VERTICES][MAX_VERTICES];

// Initialize the distance matrix with the graph


for (int i = 0; i < num_vertices; i++) {
for (int j = 0; j < num_vertices; j++) {
dist[i][j] = graph[i][j];
}
}

// Perform the Floyd-Warshall algorithm


for (int k = 0; k < num_vertices; k++) {
for (int i = 0; i < num_vertices; i++) {
for (int j = 0; j < num_vertices; j++) {
if (dist[i][k] + dist[k][j] < dist[i][j]) {
dist[i][j] = dist[i][k] + dist[k][j];
}
}
}
}

// Print the shortest distance matrix


printf("Shortest Distance Matrix:\n");
for (int i = 0; i < num_vertices; i++) {
for (int j = 0; j < num_vertices; j++) {
if (dist[i][j] == INF) {
printf("INF ");
} else {
printf("%d ", dist[i][j]);
}
}
printf("\n");
}
}

int main() {
int num_vertices;
printf("Enter the number of vertices in the graph: ");
scanf("%d", &num_vertices);

int graph[MAX_VERTICES][MAX_VERTICES];
printf("Enter the adjacency matrix:\n");

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


for (int j = 0; j < num_vertices; j++) {
scanf("%d", &graph[i][j]);
}
}

floyd_warshall(graph, num_vertices);

return 0;
}

Q2:

#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>

struct Item {
int weight;
int value;
double ratio;
};

int compare(const void* a, const void* b) {


struct Item* item1 = (struct Item*)a;
struct Item* item2 = (struct Item*)b;
return (item2->ratio - item1->ratio) > 0 ? 1 : -1;
}

void fractional_knapsack(struct Item items[], int num_items, int capacity) {


qsort(items, num_items, sizeof(struct Item), compare);

double total_value = 0.0;


double total_weight = 0.0;

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


if (items[i].weight <= capacity) {
total_value += items[i].value;
total_weight += items[i].weight;
capacity -= items[i].weight;
} else {
total_value += (double)(items[i].value * capacity) / items[i].weight;
total_weight += capacity;
capacity = 0;
}

if (capacity == 0)
break;
}

printf("Maximum value: %.2lf\n", total_value);

printf("item-weight\n");
for (int i = 0; i < num_items; i++) {
if (items[i].weight <= capacity) {
printf("%d-%d\n", i + 1, items[i].weight);
} else {
printf("%d-%.1lf\n", i + 1, (double)(items[i].value * capacity) / items[i].weight);
}

if (capacity == 0)
break;
}
}

int main() {
int num_items;
printf("Enter the number of items: ");
scanf("%d", &num_items);

struct Item items[num_items];

printf("Enter the weights of the items: ");


for (int i = 0; i < num_items; i++) {
scanf("%d", &items[i].weight);
}

printf("Enter the values of the items: ");


for (int i = 0; i < num_items; i++) {
scanf("%d", &items[i].value);
}

int capacity;
printf("Enter the maximum capacity of the knapsack: ");
scanf("%d", &capacity);

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


items[i].ratio = (double)items[i].value / items[i].weight;
}
fractional_knapsack(items, num_items, capacity);

return 0;
}

Q3:

#include <stdio.h>
#include <stdlib.h>

int compare(const void *a, const void *b) {


return (*(int *)a - *(int *)b);
}

int minimum_computation_cost(int n, int arr[]) {


qsort(arr, n, sizeof(int), compare); // Sort the array in ascending order
int total_cost = 0;

while (n > 1) {
// Take the two smallest elements
int smallest1 = arr[0];
int smallest2 = arr[1];

// Calculate the cost of merging and add it to totalCost


total_cost += smallest1 + smallest2;

// Append the merged file size to arr


arr[1] = smallest1 + smallest2;

// Shift the elements in the array to remove the merged files


for (int i = 2; i < n; i++) {
arr[i - 1] = arr[i];
}

// Decrement the size of the array


n--;

// Sort the array again in ascending order


qsort(arr, n, sizeof(int), compare);
}

return total_cost;
}

int main() {
int n;
printf("Enter the size of the array: ");
scanf("%d", &n);

int arr[n];
printf("Enter the array elements: ");
for (int i = 0; i < n; i++) {
scanf("%d", &arr[i]);
}

int cost = minimum_computation_cost(n, arr);


printf("Minimum computation cost to merge all files: %d\n", cost);

return 0;
}

WEEK 10: Solution

Q1:

#include <stdio.h>
#include <stdlib.h>

typedef struct {
int index;
int startTime;
int finishTime;
} Activity;

int compare(const void *a, const void *b) {


return ((Activity *)a)->finishTime - ((Activity *)b)->finishTime;
}

void selectNonConflictingActivities(int n, int startTimes[], int finishTimes[]) {


Activity activities[n];
for (int i = 0; i < n; i++) {
activities[i].index = i + 1;
activities[i].startTime = startTimes[i];
activities[i].finishTime = finishTimes[i];
}

qsort(activities, n, sizeof(Activity), compare);

int count = 1;
int lastSelected = 0;

printf("No. of non-conflicting activities: %d\n", count);


printf("List of selected activities: %d", activities[lastSelected].index);

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


if (activities[i].startTime >= activities[lastSelected].finishTime) {
count++;
lastSelected = i;
printf(", %d", activities[i].index);
}
}
printf("\n");
}

int main() {
int n;
printf("Enter the number of activities: ");
scanf("%d", &n);

int startTimes[n];
printf("Enter the starting times of the activities: ");
for (int i = 0; i < n; i++) {
scanf("%d", &startTimes[i]);
}

int finishTimes[n];
printf("Enter the finishing times of the activities: ");
for (int i = 0; i < n; i++) {
scanf("%d", &finishTimes[i]);
}

selectNonConflictingActivities(n, startTimes, finishTimes);

return 0;
}

Q2:

#include <stdio.h>

void selectTasks(int n, int timeTaken[], int deadlines[]) {


int count = 0;
int selectedTasks[n];
int totalTime = 0;

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


if (totalTime + timeTaken[i] <= deadlines[i]) {
count++;
selectedTasks[count - 1] = i + 1;
totalTime += timeTaken[i];
}
}

printf("Max number of tasks = %d\n", count);


printf("Selected task numbers: ");
for (int i = 0; i < count; i++) {
printf("%d", selectedTasks[i]);
if (i != count - 1)
printf(", ");
}
printf("\n");
}

int main() {
int n;
printf("Enter the total number of tasks: ");
scanf("%d", &n);

int timeTaken[n];
printf("Enter the time taken for each task: ");
for (int i = 0; i < n; i++) {
scanf("%d", &timeTaken[i]);
}

int deadlines[n];
printf("Enter the deadlines for each task: ");
for (int i = 0; i < n; i++) {
scanf("%d", &deadlines[i]);
}

selectTasks(n, timeTaken, deadlines);

return 0;
}

Q3:

#include <stdio.h>
#include <stdlib.h>

void findMajorityAndMedian(int n, int elements[]) {


int count = 0;
int candidate = 0;

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


if (count == 0) {
candidate = elements[i];
count = 1;
} else if (elements[i] == candidate) {
count++;
} else {
count--;
}
}

count = 0;
for (int i = 0; i < n; i++) {
if (elements[i] == candidate) {
count++;
}
}
printf("Majority element: %s\n", (count > n / 2) ? "yes" : "no");

// Sorting the array in ascending order


for (int i = 0; i < n - 1; i++) {
for (int j = 0; j < n - i - 1; j++) {
if (elements[j] > elements[j + 1]) {
int temp = elements[j];
elements[j] = elements[j + 1];
elements[j + 1] = temp;
}
}
}

printf("Median: ");
if (n % 2 == 1) {
printf("%d\n", elements[n / 2]);
} else {
int median1 = elements[n / 2 - 1];
int median2 = elements[n / 2];
printf("%d\n", (median1 + median2) / 2);
}
}

int main() {
int n;
printf("Enter the size of the array: ");
scanf("%d", &n);

int elements[n];
printf("Enter the elements of the array: ");
for (int i = 0; i < n; i++) {
scanf("%d", &elements[i]);
}

findMajorityAndMedian(n, elements);

return 0;
}

WEEK 11: Solutions

Q1:

#include <stdio.h>
#include <limits.h>

#define MAX_SIZE 100

int matrixChainMultiplication(int n, int dimensions[][2]) {


int dp[MAX_SIZE][MAX_SIZE];
for (int i = 1; i <= n; i++) {
dp[i][i] = 0;
}

for (int chainLength = 2; chainLength <= n; chainLength++) {


for (int i = 1; i <= n - chainLength + 1; i++) {
int j = i + chainLength - 1;
dp[i][j] = INT_MAX;

for (int k = i; k < j; k++) {


int cost = dp[i][k] + dp[k+1][j] + dimensions[i-1][0] * dimensions[k][1] * dimensions[j][1];
if (cost < dp[i][j]) {
dp[i][j] = cost;
}
}
}
}

return dp[1][n];
}

int main() {
int n;
printf("Enter the number of matrices: ");
scanf("%d", &n);

int dimensions[MAX_SIZE][2];
printf("Enter the dimensions of the matrices:\n");
for (int i = 0; i < n; i++) {
scanf("%d %d", &dimensions[i][0], &dimensions[i][1]);
}

int minOperations = matrixChainMultiplication(n, dimensions);

printf("Minimum number of operations: %d\n", minOperations);

return 0;
}

Q2:

#include <stdio.h>

#define MAX_SIZE 100

int coinChange(int numCoins, int coinValues[], int N) {


int dp[MAX_SIZE] = {0};

dp[0] = 1;

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


for (int j = coinValues[i]; j <= N; j++) {
dp[j] += dp[j - coinValues[i]];
}
}

return dp[N];
}

int main() {
int numCoins;
printf("Enter the number of coins: ");
scanf("%d", &numCoins);

int coinValues[MAX_SIZE];
printf("Enter the values of the coins: ");
for (int i = 0; i < numCoins; i++) {
scanf("%d", &coinValues[i]);
}

int N;
printf("Enter the value of N: ");
scanf("%d", &N);

int numWays = coinChange(numCoins, coinValues, N);

printf("Number of ways: %d\n", numWays);

return 0;
}

Q3:

#include <stdio.h>
#include <stdbool.h>

#define MAX_SIZE 100

bool subsetSumPartition(int n, int set[]) {


int totalSum = 0;
for (int i = 0; i < n; i++) {
totalSum += set[i];
}

if (totalSum % 2 != 0) {
return false;
}

int targetSum = totalSum / 2;

bool dp[MAX_SIZE][MAX_SIZE] = {false};


dp[0][0] = true;

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


for (int j = 0; j <= targetSum; j++) {
dp[i][j] = dp[i-1][j];
if (j >= set[i-1]) {
dp[i][j] = dp[i][j] || dp[i-1][j-set[i-1]];
}
}
}

return dp[n][targetSum];
}

int main() {
int n;
printf("Enter the number of elements: ");
scanf("%d", &n);

int set[MAX_SIZE];
printf("Enter the elements of the set: ");
for (int i = 0; i < n; i++) {
scanf("%d", &set[i]);
}

bool isPossible = subsetSumPartition(n, set);

if (isPossible) {
printf("yes\n");
} else {
printf("no\n");
}

return 0;
}

You might also like