Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                

DAA Model Lab - 230412 - 112849

Download as pdf or txt
Download as pdf or txt
You are on page 1of 56

SET - 1

1 A Student named Ramu have given an array of elements to sort in ascending


order
by her teacher Lalitha. Ramu is too lazy to sort the elements so he divided the
array into two parts and given to two of his friends. His two friends are also
lazy
to sort So, each of them has divided the array into two parts and given to two
of
their friends. The process continues until each boy gets one element and they
finally merge all the elements. Now your task is to find which person gets
which
elements.
Input format
First line will contain a integer n.
Each testcase contains of a single line of input of n integers.
Output format
i person is given with these numbers : numbers
Constraints
0>= n <=10000
0>= a[i] <=10000

Program:
#include <stdio.h>

// Function to merge two sub-arrays and sort them


void merge(int arr[], int left[], int leftSize, int right[], int rightSize) {
int i = 0, j = 0, k = 0;

while (i < leftSize && j < rightSize) {


if (left[i] < right[j]) {
arr[k++] = left[i++];
} else {
arr[k++] = right[j++];
}
}
while (i < leftSize) {
arr[k++] = left[i++];
}
while (j < rightSize) {
arr[k++] = right[j++];
}
}
// Function to perform recursive merge sort on an array
void mergeSort(int arr[], int n) {
if (n <= 1) {
return;
}

int mid = n / 2;
int left[mid];
int right[n - mid];

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


left[i] = arr[i];
}

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


right[i - mid] = arr[i];
}

mergeSort(left, mid);
mergeSort(right, n - mid);

merge(arr, left, mid, right, n - mid);


}

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

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

// Sort the array in ascending order using merge sort


mergeSort(arr, n);

printf("Person 1 is given with element: %d\n", arr[0]);

int person = 2;
int i = 1;
while (i < n) {
printf("Person %d is given with element: %d\n", person, arr[i]);
i *= 2;
person++;
}
return 0;
}
2 You are given an array of N integers and your task is to sort the array using the
following operations.
In one operation you can select a sub-array of the array and sort it. The cost of
performing such an operation will be the square of the length of the sub-array
you are sorting.
Your task is to find the minimum cost of sorting the whole array.
Input Format:
The first line contains a single integer T representing the number of test cases.
Then each test case follows.
The first line of each test case contains one integers N denoting the number of
elements in the array.
The next line of each test case contains N integers of the array.
Output Format:
For each test case, print the minimum cost required to sort the whole array.
Constraints:
1 <= T <= 5
3 <= N <= 105
1 <= arr[i] <= 109

Program:
#include <stdio.h>
#include <math.h>

// Function to swap two integers


void swap(int *a, int *b) {
int temp = *a;
*a = *b;
*b = temp;
}

// Function to partition the array using the last element as pivot


int partition(int arr[], int low, int high) {
int pivot = arr[high];
int i = low - 1;

for (int j = low; j <= high - 1; j++) {


if (arr[j] <= pivot) {
i++;
swap(&arr[i], &arr[j]);
}
}

swap(&arr[i + 1], &arr[high]);


return i + 1;
}
// Function to perform quick sort on the array
void quickSort(int arr[], int low, int high) {
if (low < high) {
int pi = partition(arr, low, high);
quickSort(arr, low, pi - 1);
quickSort(arr, pi + 1, high);
}
}

// Function to find the minimum cost of sorting the whole array


int findMinimumCost(int arr[], int n) {
quickSort(arr, 0, n - 1); // Sort the array initially

int cost = 0;
for (int i = n - 1; i >= 0; i--) {
int subarray_length = n - i; // Length of sub-array to be sorted
cost += subarray_length * subarray_length; // Add cost of sorting the
sub-array
}

return cost;
}

int main() {
int t;
printf("Enter the number of test cases: ");
scanf("%d", &t);

while (t--) {
int n;
printf("Enter the number of elements in the array: ");
scanf("%d", &n);

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

int min_cost = findMinimumCost(arr, n);


printf("Minimum cost required to sort the whole array: %d\n", min_cost);
}

return 0;
}
SET - 2

1 Write a program to implement Merge sort.


Input format
First line will contain a integer n.
Each testcase contains of a single line of input of n integers.
Output format
i person is given with these numbers : numbers
Constraints
0>= n <=10000
0>= a[i] <=10000

Program:
#include <stdio.h>

// Function to merge two sub-arrays


void merge(int arr[], int left[], int left_size, int right[], int right_size) {
int i = 0, j = 0, k = 0;

while (i < left_size && j < right_size) {


if (left[i] <= right[j]) {
arr[k++] = left[i++];
} else {
arr[k++] = right[j++];
}
}

while (i < left_size) {


arr[k++] = left[i++];
}

while (j < right_size) {


arr[k++] = right[j++];
}
}

// Function to perform merge sort


void mergeSort(int arr[], int n) {
if (n > 1) {
int mid = n / 2;
int left[mid];
int right[n - mid];

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


left[i] = arr[i];
}

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


right[i - mid] = arr[i];
}

mergeSort(left, mid);
mergeSort(right, n - mid);

merge(arr, left, mid, right, n - mid);


}
}

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

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

mergeSort(arr, n);

printf("Sorted array: ");


for (int i = 0; i < n; i++) {
printf("%d ", arr[i]);
}

return 0;
}

2 There are N cities and Demon is in city 1. Now, there are M pair of roads
between
some cities and each of the roads have cost to travel by it. The cost to travel
from
city c1 to ck is 1*w1 + 2*w2 + 3*w3+......+(k-1)*wk-1 where wi is the cost to
travel from city pi to city pi+1. Demon is lazy and so he wants you to find the
minimum cost to travel from city 1 to every other city from 1 to N. If there
exists
no path to travel from city 1 to city i, print -1.
Note: There can be self-loop roads or multiple edge roads. All the roads are
bidirectional.
Input Format:
The first line contains two space-separated integers n and m - the number of
nodes
and edges respectively. The next m lines contain three space-separated integers
x,
y, and w - representing an edge between x and y with cost w
Output Format:
Output n lines. In the ith line, output the minimum distance from city 1 to the
ith
city. If there exists no such path, output -1.
Constraints:
1<=n<=3000
0<=m<=10000
1<=x,y<=n
1<=w<=1e9

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

#define MAXN 3001


#define INF INT_MAX

int n, m; // Number of nodes and edges


int graph[MAXN][MAXN]; // Graph representation
int dist[MAXN]; // Distance array to store minimum distance from city 1
bool visited[MAXN]; // Visited array to mark visited nodes

// Function to find the minimum distance using Dijkstra's algorithm


void dijkstra() {
for (int i = 1; i <= n; i++) {
dist[i] = INF; // Initialize distances to infinity
visited[i] = false; // Mark all nodes as not visited
}

dist[1] = 0; // Distance from city 1 to itself is 0

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


int u = -1;

// Find the node with minimum distance that is not visited yet
for (int j = 1; j <= n; j++) {
if (!visited[j] && (u == -1 || dist[j] < dist[u])) {
u = j;
}
}

visited[u] = true; // Mark the node as visited

// Update distances of adjacent nodes of u


for (int v = 1; v <= n; v++) {
if (graph[u][v] != 0 && !visited[v] && dist[u] != INF && (dist[u] +
graph[u][v] < dist[v])) {
dist[v] = dist[u] + graph[u][v];
}
}
}
}

int main() {
printf("Enter the number of nodes and edges: ");
scanf("%d %d", &n, &m);

// Initialize graph with 0 weight


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

// Input edges and their weights


printf("Enter the edges and their weights:\n");
for (int i = 0; i < m; i++) {
int x, y, w;
scanf("%d %d %d", &x, &y, &w);
graph[x][y] = w;
graph[y][x] = w; // Graph is bidirectional
}

dijkstra(); // Call Dijkstra's algorithm to find the minimum distance

// Output the minimum distance from city 1 to every other city


printf("Minimum distance from city 1 to every other city:\n");
for (int i = 2; i <= n; i++) {
if (dist[i] == INF) {
printf("-1\n"); // If no path exists, print -1
} else {
printf("%d\n", dist[i]);
}
}
return 0;
}

SET - 3

1 You are given n objects, a knapsack of capacity c, array v, and array w. The ith
object has value v[i] and weight w[i].
Determine the maximum total value that you can get by selecting objects in
such
a manner that their sum of weights is not greater than the capacity c.
Hint: Use Dynamic programming.
Input format:
First line: Two integers n and c denoting the number of objects and capacity of
the knapsack ( 1 <= n<= 10^3 and 1 <= C <= 2*10^6 ) .
Second line: n integers (0 <= Vi <= 50)
Third line: n integers ( 10 <=Wi <= 2*10^6)
Output format:
Print a single integer denoting the maximum value that you can get by
selecting
the objects.
Program:
#include <stdio.h>

#define MAXN 1001


#define MAXC 2000001

int n, c; // Number of objects and capacity of knapsack


int v[MAXN], w[MAXN]; // Arrays to store values and weights of objects
int dp[MAXN][MAXC]; // Dynamic programming table

// Function to find the maximum value using dynamic programming


int knapsack() {
for (int i = 0; i <= n; i++) {
for (int j = 0; j <= c; j++) {
if (i == 0 || j == 0) {
dp[i][j] = 0; // Base case: when there are no objects or knapsack has
no capacity
} else if (w[i - 1] <= j) {
dp[i][j] = (v[i - 1] + dp[i - 1][j - w[i - 1]]) > dp[i - 1][j]
? (v[i - 1] + dp[i - 1][j - w[i - 1]])
: dp[i - 1][j]; // Include current object in the knapsack
} else {
dp[i][j] = dp[i - 1][j]; // Exclude current object from the knapsack
}
}
}

return dp[n][c]; // Maximum value that can be obtained


}

int main() {
printf("Enter the number of objects and capacity of knapsack: ");
scanf("%d %d", &n, &c);

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


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

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


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

int max_value = knapsack(); // Call knapsack function to find the maximum


value

printf("Maximum value that can be obtained: %d\n", max_value);

return 0;
}

2 Given a chess board having NxN cells, you need to place N queens on the
board
in such a way that no queen attacks any other queen.
Input Format:
The only line of input consists of a single integer denoting N.
Output Format:
If it is possible to place all the N queens in such a way that no queen attacks
another
queen, then print N lines having N integers. The integer in ith line and jth
column
will denote the cell (i,j) of the board and should be 1 if a queen is placed at (i,j)
otherwise 0. If there are more than way of placing queens print any of them. If
it
is not possible to place all N queens in the desired way, then print "Not
possible"
(without quotes).
Constraints:
1 <= N <= 10
Program:
#include <stdio.h>

#define MAXN 11 // Maximum value of N

int N; // Size of chess board


int board[MAXN][MAXN]; // Chess board

// Function to check if a queen can be placed at the given cell


int isSafe(int row, int col) {
// Check if there is any queen in the same row
for (int i = 0; i < N; i++) {
if (board[row][i]) {
return 0;
}
}

// Check if there is any queen in the same column


for (int i = 0; i < N; i++) {
if (board[i][col]) {
return 0;
}
}

// Check if there is any queen in the upper diagonal


for (int i = row, j = col; i >= 0 && j >= 0; i--, j--) {
if (board[i][j]) {
return 0;
}
}

// Check if there is any queen in the lower diagonal


for (int i = row, j = col; i < N && j >= 0; i++, j--) {
if (board[i][j]) {
return 0;
}
}

return 1; // If it is safe to place a queen at the given cell


}

// Function to solve N-Queens problem using backtracking


int solveNQueens(int col) {
if (col == N) {
return 1; // All queens have been placed successfully
}
for (int row = 0; row < N; row++) {
if (isSafe(row, col)) {
board[row][col] = 1; // Place queen at current cell

if (solveNQueens(col + 1)) {
return 1; // Move to the next column
}

board[row][col] = 0; // Backtrack and remove queen from current cell


}
}

return 0; // No solution found


}

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

// Initialize the chess board with 0


for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
board[i][j] = 0;
}
}

if (solveNQueens(0)) {
printf("Queens placement:\n");
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
printf("%d ", board[i][j]);
}
printf("\n");
}
} else {
printf("Not possible\n");
}

return 0;
}
SET - 4
1 Write a program to implement Quick Sort.
Program:
#include <stdio.h>

// Function to swap two elements in an array


void swap(int* a, int* b) {
int t = *a;
*a = *b;
*b = t;
}

// Function to partition the array and return the pivot index


int partition(int arr[], int low, int high) {
int pivot = arr[low]; // Choose the first element as pivot
int i = low + 1; // Index to track elements smaller than pivot

// Iterate through the array and swap elements smaller than pivot
// to the left side of the pivot
for (int j = low + 1; j <= high; j++) {
if (arr[j] < pivot) {
swap(&arr[i], &arr[j]);
i++;
}
}

// Place the pivot at its correct position


swap(&arr[low], &arr[i - 1]);

return i - 1; // Return the pivot index


}

// Function to implement Quick Sort


void quickSort(int arr[], int low, int high) {
if (low < high) {
int pivotIndex = partition(arr, low, high); // Get the pivot index

// Recursively sort the left and right subarrays of the pivot


quickSort(arr, low, pivotIndex - 1);
quickSort(arr, pivotIndex + 1, high);
}
}

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

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

printf("Original array: ");


for (int i = 0; i < n; i++) {
printf("%d ", arr[i]);
}
printf("\n");

quickSort(arr, 0, n - 1); // Call Quick Sort

printf("Sorted array: ");


for (int i = 0; i < n; i++) {
printf("%d ", arr[i]);
}
printf("\n");

return 0;
}

2 The travelling salesman has a map containing m*n squares. He starts from
the top left corner and visits every cell exactly once and returns to his initial
position (top left). The time taken for the salesman to move from a square to
its
neighbor might not be the same. Two squares are considered adjacent if they
share
a common edge and the time taken to reach square b from square a and
vice-versa
are the same. Can you figure out the shortest time in which the salesman can
visit
every cell and get back to his initial position?
Hint: Use Branch and Bound
Program:
#include <stdio.h>
#include <limits.h>

// Function to find the minimum of two integers


int min(int a, int b) {
return (a < b) ? a : b;
}
// Function to solve Traveling Salesman Problem using dynamic programming
int tspDynamicProgramming(int m, int n, int grid[10][10], int dp[10][1024]) {
int VISITED_ALL = (1 << n) - 1;

// Base case: if all cells are visited, return the time taken to go back to the
top left corner
if (dp[0][VISITED_ALL] != -1) {
return dp[0][VISITED_ALL];
}

// If not all cells are visited, initialize minimum time taken to maximum
integer value
int min_time = INT_MAX;

// Iterate over all unvisited cells


for (int i = 0; i < n; i++) {
if (!(VISITED_ALL & (1 << i))) {
int new_visited = VISITED_ALL | (1 << i);
int time = grid[m][i] + tspDynamicProgramming(i, n, grid, dp);
min_time = min(min_time, time);
}
}

// Store the minimum time taken in the dp table


dp[m][VISITED_ALL] = min_time;
return min_time;
}

int main() {
int m, n;
int grid[10][10];

// Input the dimensions of the grid


printf("Enter the dimensions of the grid (m x n): ");
scanf("%d %d", &m, &n);

// Input the time taken to move between cells


printf("Enter the time taken to move between cells:\n");
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
scanf("%d", &grid[i][j]);
}
}

// Initialize dp table with -1


int dp[10][1024];
for (int i = 0; i < m; i++) {
for (int j = 0; j < (1 << n); j++) {
dp[i][j] = -1;
}
}

// Call the tspDynamicProgramming function to solve the problem


int min_time = tspDynamicProgramming(0, n, grid, dp);

// Print the minimum time taken to visit every cell and return to the top left
corner
printf("Minimum time taken: %d\n", min_time);

return 0;
}

SET - 5

1 Given a Directed and Acyclic Graph having N vertices and M edges, print
topological sorting of the vertices.
Program:
#include <stdio.h>
#include <stdbool.h>

#define MAX_SIZE 100

// Function to perform Depth-First Search (DFS) on the graph


void dfs(int vertex, bool visited[], int adjMatrix[][MAX_SIZE], int N, int
stack[]) {
visited[vertex] = true;

// Recursively visit all adjacent vertices


for (int i = 0; i < N; i++) {
if (adjMatrix[vertex][i] == 1 && !visited[i]) {
dfs(i, visited, adjMatrix, N, stack);
}
}

// Push the current vertex to stack after visiting all its adjacent vertices
stack[N] = vertex;
}

// Function to perform topological sorting of the DAG


void topologicalSort(int adjMatrix[][MAX_SIZE], int N) {
bool visited[MAX_SIZE] = {false}; // Array to keep track of visited vertices
int stack[MAX_SIZE]; // Stack to store the topological sorting order
int stackIndex = N - 1; // Index to keep track of the top of the stack

// Perform DFS on all unvisited vertices


for (int i = 0; i < N; i++) {
if (!visited[i]) {
dfs(i, visited, adjMatrix, N, stack);
}
}

// Print the topological sorting order


printf("Topological Sorting Order: ");
for (int i = 0; i < N; i++) {
printf("%d ", stack[stackIndex--]);
}
printf("\n");
}

int main() {
int N, M;
int adjMatrix[MAX_SIZE][MAX_SIZE];

// Input the number of vertices and edges


printf("Enter the number of vertices: ");
scanf("%d", &N);
printf("Enter the number of edges: ");
scanf("%d", &M);

// Initialize the adjacency matrix with zeros


for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
adjMatrix[i][j] = 0;
}
}

// Input the edges of the graph


printf("Enter the edges (source vertex and destination vertex):\n");
for (int i = 0; i < M; i++) {
int u, v;
scanf("%d %d", &u, &v);
adjMatrix[u][v] = 1;
}

// Perform topological sorting


topologicalSort(adjMatrix, N);
return 0;
}

2 The task is very simple you ar given an array of n numbers. You need to print
all
the unique subsets of the array having sum K in sorted order.
Note that each of the subset you print should be in sorted order also also a
smaller
subset should be printed first i.e all subsets should also be printed in sorted
order.
A subset A is smaller than subset B if there exists A[i] < B[i] for the smallest
possible i.
Please not that you only need to print unique subsets i/e dont print them twice
if
they accur more than once.
INPUT FORMAT:
First line contains 2 integers N and K
Second line contains N space sperated integers
OUTPUT FORMAT:
Output unique subsets having sum K in sorted order
CONSTRAINTS:
1 <= N <= 15
1 <= K <= 10000
1 <= A[i] <= 100
Program:
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>

// Function to compare two integers (required for qsort)


int compareIntegers(const void* a, const void* b) {
return (*(int*)a - *(int*)b);
}

// Function to print subsets with sum K


void printSubsetsWithSumK(int arr[], int N, int K, int subset[], int subsetSize,
int index) {
if (K == 0) {
// Print the subset with sum K
for (int i = 0; i < subsetSize; i++) {
printf("%d ", subset[i]);
}
printf("\n");
return;
}
if (index == N) {
return;
}

// Include the current element in the subset


subset[subsetSize] = arr[index];
printSubsetsWithSumK(arr, N, K - arr[index], subset, subsetSize + 1, index
+ 1);

// Exclude the current element from the subset


printSubsetsWithSumK(arr, N, K, subset, subsetSize, index + 1);
}

int main() {
int N, K;
int arr[15]; // Maximum array size as per constraint
int subset[15]; // Maximum subset size as per constraint

// Input the number of elements in the array and the required sum
printf("Enter the number of elements in the array: ");
scanf("%d", &N);
printf("Enter the required sum K: ");
scanf("%d", &K);

// Input the elements of the array


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

// Sort the array in ascending order


qsort(arr, N, sizeof(int), compareIntegers);

// Call the function to print subsets with sum K


printf("Unique subsets with sum K:\n");
printSubsetsWithSumK(arr, N, K, subset, 0, 0);

return 0;
}

SET - 6

1 Write a program to implement Warshall’s and Floyd’s Algorithm.


Hint: Use Dynamic Programming
Input Format:
1. First line contain three integers N M K.
2. Next M lines contain three integers U V W, denoting a road between city U
and city v with Toll Charge W.
Output Format :
Print N space separated integers , denoting the minimum charge we require to
pay for each city , where first integer represent cost for City 1, second for City
2
and so on.
Program:
#include <stdio.h>
#include <stdbool.h>
#include <limits.h>

// Function to implement Warshall's Algorithm


void warshall(int graph[][101], int N) {
for (int k = 1; k <= N; k++) {
for (int i = 1; i <= N; i++) {
for (int j = 1; j <= N; j++) {
if (graph[i][k] != INT_MAX && graph[k][j] != INT_MAX &&
graph[i][j] > graph[i][k] + graph[k][j]) {
graph[i][j] = graph[i][k] + graph[k][j];
}
}
}
}
}

// Function to implement Floyd's Algorithm


void floyd(int graph[][101], int N) {
for (int k = 1; k <= N; k++) {
for (int i = 1; i <= N; i++) {
for (int j = 1; j <= N; j++) {
if (graph[i][k] != INT_MAX && graph[k][j] != INT_MAX &&
graph[i][j] > graph[i][k] + graph[k][j]) {
graph[i][j] = graph[i][k] + graph[k][j];
}
}
}
}
}

int main() {
int N, M, K;
int graph[101][101]; // Maximum N as per constraint
int u, v, w;

// Input the number of cities, number of roads, and maximum toll charge
printf("Enter the number of cities, number of roads, and maximum toll
charge (N M K): ");
scanf("%d %d %d", &N, &M, &K);

// Initialize the graph with maximum toll charge


for (int i = 1; i <= N; i++) {
for (int j = 1; j <= N; j++) {
graph[i][j] = INT_MAX;
}
graph[i][i] = 0;
}

// Input the roads and toll charges


printf("Enter the roads and toll charges (U V W):\n");
for (int i = 0; i < M; i++) {
scanf("%d %d %d", &u, &v, &w);
graph[u][v] = w;
}

// Call Warshall's Algorithm to find shortest paths


warshall(graph, N);

// Print the shortest path for each city


printf("Minimum charges for each city:\n");
for (int i = 1; i <= N; i++) {
printf("%d ", graph[1][i]); // City 1 is the source city
}
printf("\n");

return 0;
}

2 Write a program to implement Ford-Fulkerson algorithm is a greedy approach


for
calculating the maximum possible flow in a network or a graph.
A term, flow network, is used to describe a network of vertices and edges with
a
source (S) and a sink (T). Each vertex, except S and T, can receive and send an
equal amount of stuff through it. S can only send and T can only receive stuff.
Program:
#include <stdio.h>
#include <stdbool.h>
#define MAX_N 100 // Maximum number of vertices in the graph

int graph[MAX_N][MAX_N]; // Adjacency matrix representing the graph


bool visited[MAX_N]; // Array to keep track of visited vertices
int parent[MAX_N]; // Array to keep track of parent vertices in augmenting
path
int N, M; // Number of vertices and edges in the graph

// Function to find the minimum of two integers


int min(int a, int b) {
return (a < b) ? a : b;
}

// Function to perform Depth-First Search (DFS) on the graph to find an


augmenting path
bool dfs(int u, int t) {
visited[u] = true;

for (int v = 0; v < N; v++) {


if (!visited[v] && graph[u][v] > 0) {
parent[v] = u;

if (v == t) {
return true; // Augmenting path found
}

if (dfs(v, t)) {
return true;
}
}
}

return false; // No augmenting path found


}

// Function to implement Ford-Fulkerson algorithm


int fordFulkerson(int s, int t) {
int maxFlow = 0;

while (dfs(s, t)) {


// Find the bottleneck capacity of the augmenting path
int bottleneck = 1e9;
for (int v = t; v != s; v = parent[v]) {
int u = parent[v];
bottleneck = min(bottleneck, graph[u][v]);
}
// Update the residual capacities of the edges along the augmenting path
for (int v = t; v != s; v = parent[v]) {
int u = parent[v];
graph[u][v] -= bottleneck;
graph[v][u] += bottleneck;
}

maxFlow += bottleneck;

// Reset the visited array for the next DFS


for (int i = 0; i < N; i++) {
visited[i] = false;
}
}

return maxFlow;
}

int main() {
int source, sink;
int u, v, capacity;

// Input the number of vertices, edges, and source/sink vertices


printf("Enter the number of vertices, edges, source, and sink (N M S T):\n");
scanf("%d %d %d %d", &N, &M, &source, &sink);

// Initialize the graph


for (int i = 0; i < N; i++) {
visited[i] = false;
parent[i] = -1;
for (int j = 0; j < N; j++) {
graph[i][j] = 0;
}
}
// Input the capacities of edges
printf("Enter the capacities of edges (U V Capacity):\n");
for (int i = 0; i < M; i++) {
scanf("%d %d %d", &u, &v, &capacity);
graph[u - 1][v - 1] = capacity;
}
// Calculate the maximum flow using Ford-Fulkerson algorithm
int maxFlow = fordFulkerson(source - 1, sink - 1);
printf("Maximum Flow: %d\n", maxFlow);
return 0;
}
SET - 7
1 You are given an array A[] of N numbers. Implement Quick Sort Algorithm.
Input:
First line will contain N which denotes the number of numbers.
Second line will contain an Array [] A[].
Output: Print the sorted numbers in ascending order
Program:
#include <stdio.h>

// Function to swap two elements in an array


void swap(int* a, int* b) {
int temp = *a;
*a = *b;
*b = temp;
}

// Function to partition the array and return the pivot index


int partition(int arr[], int low, int high) {
int pivot = arr[high]; // Choose the last element as pivot
int i = low - 1; // Index of smaller element

for (int j = low; j < high; j++) {


// If current element is smaller than or equal to pivot
if (arr[j] <= pivot) {
i++;
swap(&arr[i], &arr[j]);
}
}

swap(&arr[i + 1], &arr[high]);


return i + 1; // Return the pivot index
}

// Function to implement Quick Sort algorithm


void quickSort(int arr[], int low, int high) {
if (low < high) {
int pi = partition(arr, low, high);

// Recursively sort the two subarrays


quickSort(arr, low, pi - 1);
quickSort(arr, pi + 1, high);
}
}

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

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

// Call the Quick Sort function to sort the array


quickSort(arr, 0, N - 1);

printf("Sorted array in ascending order: ");


for (int i = 0; i < N; i++) {
printf("%d ", arr[i]);
}
printf("\n");

return 0;
}

2 Given an undirected graph and a starting node, determine the lengths of the
shortest paths from the starting node to all other nodes in the graph. If a node
is
unreachable, its distance is -1. Nodes will be numbered consecutively from to ,
and edges will have varying distances or lengths using dijkstra’s algorithm.
Program:
#include <stdio.h>
#include <stdbool.h>
#include <limits.h>

#define MAX_NODES 1000 // Maximum number of nodes in the graph


#define INF INT_MAX // Infinity

// Function to find the minimum distance vertex from the set of unvisited
vertices
int minDistance(int dist[], bool visited[], int V) {
int min = INF;
int min_index;

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


if (!visited[v] && dist[v] <= min) {
min = dist[v];
min_index = v;
}
}

return min_index;
}

// Function to print the shortest path distances from the source node
void printShortestDistances(int dist[], int V, int src) {
printf("Shortest path distances from node %d:\n", src);
for (int i = 0; i < V; i++) {
if (dist[i] == INF) {
printf("Node %d is unreachable\n", i);
} else {
printf("Node %d: %d\n", i, dist[i]);
}
}
}

// Function to implement Dijkstra's algorithm to find the shortest path


distances
void dijkstra(int graph[MAX_NODES][MAX_NODES], int V, int src) {
int dist[MAX_NODES]; // Array to store shortest path distances
bool visited[MAX_NODES]; // Array to keep track of visited nodes

// Initialize dist[] and visited[]


for (int i = 0; i < V; i++) {
dist[i] = INF;
visited[i] = false;
}

dist[src] = 0; // Distance of source node from itself is 0

for (int count = 0; count < V - 1; count++) {


int u = minDistance(dist, visited, V); // Find the minimum distance vertex

visited[u] = true; // Mark the vertex as visited

// Update dist[] of adjacent vertices of u


for (int v = 0; v < V; v++) {
if (!visited[v] && graph[u][v] && dist[u] != INF && dist[u] +
graph[u][v] < dist[v]) {
dist[v] = dist[u] + graph[u][v];
}
}
}

printShortestDistances(dist, V, src); // Print the shortest path distances


}

int main() {
int V; // Number of nodes in the graph
printf("Enter the number of nodes in the graph: ");
scanf("%d", &V);

int graph[MAX_NODES][MAX_NODES]; // Adjacency matrix


representation of the graph
printf("Enter the adjacency matrix of the graph:\n");
for (int i = 0; i < V; i++) {
for (int j = 0; j < V; j++) {
scanf("%d", &graph[i][j]);
}
}

int src; // Source node


printf("Enter the starting node: ");
scanf("%d", &src);

dijkstra(graph, V, src); // Call Dijkstra's algorithm to find the shortest path


distances

return 0;
}

SET - 8

1 Write a program to implement prim’s algorithm for constructing minimum


spanning tree using greedy approach.
Problem Description:
Given a weighted, undirected and connected graph of V vertices and E edges.
The task is to find the sum of weights of the edges of the Minimum Spanning
Tree.
Constraints:
2 ≤ V ≤ 1000
V-1 ≤ E ≤ (V*(V-1))/2
1 ≤ w ≤ 1000
Graph is connected and doesn't contain self loops & multiple edges
Program:
#include <stdio.h>
#include <stdbool.h>
#include <limits.h>
#define MAX_NODES 1000 // Maximum number of nodes in the graph
#define INF INT_MAX // Infinity

// Function to find the vertex with minimum key value from the set of vertices
not yet included in MST
int minKey(int key[], bool mstSet[], int V) {
int min = INF;
int min_index;

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


if (!mstSet[v] && key[v] < min) {
min = key[v];
min_index = v;
}
}

return min_index;
}

// Function to print the minimum spanning tree


void printMST(int parent[], int V, int graph[MAX_NODES][MAX_NODES])
{
printf("Minimum Spanning Tree:\n");
for (int i = 1; i < V; i++) {
printf("Edge: %d - %d, Weight: %d\n", parent[i], i, graph[i][parent[i]]);
}
}

// Function to implement Prim's algorithm to find the minimum spanning tree


void primMST(int graph[MAX_NODES][MAX_NODES], int V) {
int parent[MAX_NODES]; // Array to store parent of each vertex in MST
int key[MAX_NODES]; // Array to store key values used to pick minimum
weight edge
bool mstSet[MAX_NODES]; // Array to keep track of vertices included in
MST

// Initialize key[] and mstSet[]


for (int i = 0; i < V; i++) {
key[i] = INF;
mstSet[i] = false;
}

key[0] = 0; // First vertex is always the root of MST


parent[0] = -1; // Root has no parent

for (int count = 0; count < V - 1; count++) {


int u = minKey(key, mstSet, V); // Find the vertex with minimum key
value

mstSet[u] = true; // Mark the vertex as included in MST

// Update key[] and parent[] of adjacent vertices of u


for (int v = 0; v < V; v++) {
if (graph[u][v] && !mstSet[v] && graph[u][v] < key[v]) {
parent[v] = u;
key[v] = graph[u][v];
}
}
}

printMST(parent, V, graph); // Print the minimum spanning tree


}

int main() {
int V; // Number of nodes in the graph
printf("Enter the number of nodes in the graph: ");
scanf("%d", &V);

int graph[MAX_NODES][MAX_NODES]; // Adjacency matrix


representation of the graph
printf("Enter the adjacency matrix of the graph:\n");
for (int i = 0; i < V; i++) {
for (int j = 0; j < V; j++) {
scanf("%d", &graph[i][j]);
}
}

primMST(graph, V); // Call Prim's algorithm to find the minimum spanning


tree

return 0;
}

2 An established group of scientists are working on finding solution to NP hard


problems. They claim Subset Sum as an NP-hard problem. The problem is to
determine whether there exists a subset of a given set S whose sum is a given
number K.
You are a computer engineer and you claim to solve this problem given that all
numbers in the set are non-negative. Given a set S of size N of non-negative
integers, find whether there exists a subset whose sum is K.
Input
First line of input contains T, the number of test cases. T test cases follow.
Each test case contains 2 lines. First line contains two integers N and K. Next
line contains N space separated non-negative integers (each less than 100000).
0 < T < 1000
0 < N < 1000
0 < K < 1000
Output
Output T lines, one for each test case. Every line should be either 0 or 1
depending on whether such a subset exists or not.
Program:
#include <stdio.h>
#include <stdbool.h>

// Function to check if there exists a subset of given sum using dynamic


programming
bool isSubsetSum(int arr[], int n, int sum) {
bool dp[n + 1][sum + 1];

// Initialize the first row of dp[][] to true, as sum 0 is always possible with
an empty subset
for (int i = 0; i <= n; i++) {
dp[i][0] = true;
}

// Initialize the first column of dp[][] to false, as sum greater than 0 is not
possible with an empty set
for (int i = 1; i <= sum; i++) {
dp[0][i] = false;
}

// Fill the dp[][] table in bottom-up manner


for (int i = 1; i <= n; i++) {
for (int j = 1; j <= sum; j++) {
if (arr[i - 1] <= j) {
// If the current element is less than or equal to the current sum,
// we have two options: include it or exclude it
dp[i][j] = dp[i - 1][j - arr[i - 1]] || dp[i - 1][j];
} else {
// If the current element is greater than the current sum,
// we can only exclude it
dp[i][j] = dp[i - 1][j];
}
}
}

return dp[n][sum]; // Return the final value at dp[n][sum]


}
int main() {
int T; // Number of test cases
printf("Enter the number of test cases: ");
scanf("%d", &T);

while (T--) {
int N, K; // Size of set and target sum for each test case
printf("Enter the size of set and target sum: ");
scanf("%d %d", &N, &K);

int arr[N]; // Array to store the set


printf("Enter the set of non-negative integers: ");
for (int i = 0; i < N; i++) {
scanf("%d", &arr[i]);
}

// Call isSubsetSum function to check if there exists a subset with given


sum
bool exists = isSubsetSum(arr, N, K);

// Print the result for current test case


printf("Subset with sum %d %s\n", K, exists ? "exists" : "does not exist");
}

return 0;
}

SET - 9

1 You are given an array $A$ of size $N$. Sort the array using Quick Sort and
print
the sorted array.
Input Format:
The first line of the input contains a single integer T denoting the number
of test cases. The description of T test cases follows.
The first line of each test case contains a single integer N.
The second line contains N space-separated integers 1, 2… A1, A2,…,
AN.
Output Format : for each test case print a single line containing N
spaceseparated
integers - the sorted array.
Constraints:
Program
#include <stdio.h>

// Function to swap two integers


void swap(int* a, int* b) {
int t = *a;
*a = *b;
*b = t;
}

// Function to partition the array for quicksort


int partition(int arr[], int low, int high) {
int pivot = arr[high]; // Choosing last element as pivot
int i = low - 1; // Index of smaller element

for (int j = low; j < high; j++) {


// If current element is smaller than or equal to pivot, swap it with the
element at index i+1
if (arr[j] <= pivot) {
i++;
swap(&arr[i], &arr[j]);
}
}

// Swap the pivot element with the element at index i+1, to place pivot at its
correct position
swap(&arr[i + 1], &arr[high]);

return i + 1; // Return the index of pivot element


}

// Function to perform quicksort


void quickSort(int arr[], int low, int high) {
if (low < high) {
int pivotIndex = partition(arr, low, high); // Get the index of pivot
element

// Recursively sort the two subarrays before and after pivot element
quickSort(arr, low, pivotIndex - 1);
quickSort(arr, pivotIndex + 1, high);
}
}

int main() {
int T; // Number of test cases
printf("Enter the number of test cases: ");
scanf("%d", &T);
while (T--) {
int N; // Size of array
printf("Enter the size of array: ");
scanf("%d", &N);

int arr[N]; // Array to store the elements


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

// Call quickSort function to sort the array


quickSort(arr, 0, N - 1);

// Print the sorted array


printf("Sorted array: ");
for (int i = 0; i < N; i++) {
printf("%d ", arr[i]);
}
printf("\n");
}

return 0;
}

2 The Floyd Warshall Algorithm is for solving all pairs of shortest-path


problems.
The problem is to find the shortest distances between every pair of vertices in
a
given edge-weighted directed Graph
Input:
graph[][] = { {0, 5, INF, 10},
{INF, 0, 3, INF},
{INF, INF, 0, 1},
{INF, INF, INF, 0} }
which represents the following graph
10
(0)——->(3)
| /|\
5||1
||
\|/ |
(1)——->(2)
3
Output: Shortest distance matrix
0589
INF 0 3 4
INF INF 0 1
INF INF INF 0
Program:
#include <stdio.h>

// Define a constant for infinity value


#define INF 99999

// Function to perform Floyd Warshall algorithm to find all pairs shortest path
void floydWarshall(int graph[][4], int V) {
int dist[V][V]; // 2D array to store the shortest distances

// Initialize the distance array with the given graph


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

// Perform the Floyd Warshall algorithm


for (int k = 0; k < V; k++) {
for (int i = 0; i < V; i++) {
for (int j = 0; j < V; j++) {
// If vertex k is an intermediate vertex in the shortest path from i to j,
// and the path from i to k and k to j is shorter than the current path
from i to j,
// update the shortest distance from i to 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 < V; i++) {
for (int j = 0; j < V; j++) {
if (dist[i][j] == INF) {
printf("INF ");
} else {
printf("%d ", dist[i][j]);
}
}
printf("\n");
}
}

int main() {
int graph[4][4] = {{0, 5, INF, 10},
{INF, 0, 3, INF},
{INF, INF, 0, 1},
{INF, INF, INF, 0}};

int V = 4; // Number of vertices in the graph

// Call the Floyd Warshall function to find all pairs shortest path
floydWarshall(graph, V);

return 0;
}

SET - 10

1 Given an array arr[], its starting position l and its ending position r. Sort the
array
using merge sort algorithm.
Input Format
First line: the size of the array
Second line: the array to be sorted (numbers separated by spaces)
Output Format
Output between two brackets and each number separated by a coma.
Program:
#include <stdio.h>

// Function to merge two sorted arrays


void merge(int arr[], int l, int m, int r) {
int i, j, k;
int n1 = m - l + 1;
int n2 = r - m;

// Create temporary arrays


int L[n1], R[n2];

// Copy data to temporary arrays


for (i = 0; i < n1; i++)
L[i] = arr[l + i];
for (j = 0; j < n2; j++)
R[j] = arr[m + 1 + j];

// Merge the temporary arrays back into arr[l..r]


i = 0; // Initial index of first subarray
j = 0; // Initial index of second subarray
k = l; // Initial index of merged subarray
while (i < n1 && j < n2) {
if (L[i] <= R[j]) {
arr[k] = L[i];
i++;
} else {
arr[k] = R[j];
j++;
}
k++;
}

// Copy the remaining elements of L[], if any


while (i < n1) {
arr[k] = L[i];
i++;
k++;
}

// Copy the remaining elements of R[], if any


while (j < n2) {
arr[k] = R[j];
j++;
k++;
}
}

// Function to implement merge sort algorithm


void mergeSort(int arr[], int l, int r) {
if (l < r) {
int m = l + (r - l) / 2;

// Sort first and second halves


mergeSort(arr, l, m);
mergeSort(arr, m + 1, r);

// Merge the sorted halves


merge(arr, l, m, r);
}
}
int main() {
int n;
printf("Enter the size of the array: ");
scanf("%d", &n);

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

// Call mergeSort function to sort the array


mergeSort(arr, 0, n - 1);

// Print the sorted array


printf("Sorted array: [");
for (int i = 0; i < n; i++) {
printf("%d", arr[i]);
if (i < n - 1)
printf(", ");
}
printf("]\n");

return 0;
}

2 There are N cities numbered from 0..N-1. A salesman is located at city 0. He


wishes to visit all cities exactly once and return back to city 0. There are K toll
booths. Each toll booth has a certain range of functioning. The parameters for
toll
k are given as x_k and y_k. If the salesman travels from city i to j, he has to
pay 1
dollar toll fee to each toll p having x_p >= i and y_p <= j. Calculate the
cheapest
way for the salesman to complete his tour.
Input :
The first line contains T the number of test cases. T test cases follow. The first
line of each test case contains two space seperated integers N and K. Each of
the
next K lines contains 2 integers, the ith line containing x_i and y_i (0 <=
x_i,y_i
< N). A blank line seperates two test cases.
Output :
Output T lines, one for each test case, containing the required answer.
Constraints :
1 <= T <= 50
2 <= n <= 1000
1 <= K <= 10000
Program:
#include <stdio.h>
#include <stdlib.h>

#define MAXN 1005


#define MAXK 10005

// Function to calculate the minimum toll fee


int minToll(int n, int k, int tolls[][2]) {
int dp[MAXN][MAXN]; // dp[i][j] stores the minimum toll fee to go from
city i to city j
int INF = 1e9; // Set a large value as infinity

// Initialize dp array with infinity


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

// Set toll fee for direct routes


for (int i = 0; i < k; i++) {
dp[tolls[i][0]][tolls[i][1]] = 0; // No toll fee for direct routes
}

// Dynamic programming to calculate minimum toll fee


for (int c = 0; c < n; c++) {
for (int a = 0; a < n; a++) {
for (int b = 0; b < n; b++) {
dp[a][b] = fmin(dp[a][b], dp[a][c] + dp[c][b]); // Update minimum
toll fee
}
}
}

int minFee = INF;


// Find minimum toll fee for complete tour
for (int i = 1; i < n; i++) {
if (dp[0][i] + dp[i][0] < minFee) {
minFee = dp[0][i] + dp[i][0];
}
}

return minFee;
}

int main() {
int t;
printf("Enter the number of test cases: ");
scanf("%d", &t);

while (t--) {
int n, k;
printf("Enter the number of cities and number of toll booths: ");
scanf("%d %d", &n, &k);

int tolls[MAXK][2];
printf("Enter the toll booth ranges (x_i, y_i): \n");
for (int i = 0; i < k; i++) {
scanf("%d %d", &tolls[i][0], &tolls[i][1]);
}

// Call minToll function to calculate the minimum toll fee


int minFee = minToll(n, k, tolls);

printf("Minimum toll fee for complete tour: %d\n", minFee);


}

return 0;
}

SET - 11

1 Write a program to implement 0/1 knapsack problem using dynamic


programming.
Input:
value = [ 20, 5, 10, 40, 15, 25 ]
weight = [ 1, 2, 3, 8, 7, 4 ]
int W = 10
Output:
Knapsack value is 60
value = 20 + 40 = 60
weight = 1 + 8 = 9 < W
Program:
#include <stdio.h>

// Function to implement 0/1 knapsack problem using dynamic programming


int knapsack(int value[], int weight[], int n, int W) {
int dp[n + 1][W + 1]; // dp[i][j] stores the maximum knapsack value using
first i items and j weight limit

// Initialize dp array with 0


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

// Dynamic programming to calculate maximum knapsack value


for (int i = 1; i <= n; i++) {
for (int w = 1; w <= W; w++) {
if (weight[i - 1] <= w) {
dp[i][w] = fmax(value[i - 1] + dp[i - 1][w - weight[i - 1]], dp[i -
1][w]);
} else {
dp[i][w] = dp[i - 1][w];
}
}
}

return dp[n][W];
}

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

int value[n], weight[n];


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

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


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

int W;
printf("Enter the knapsack weight limit: ");
scanf("%d", &W);

// Call knapsack function to calculate maximum knapsack value


int maxVal = knapsack(value, weight, n, W);

printf("Knapsack value is %d\n", maxVal);

return 0;
}

2 Given a directed flow network where each edge has a capacity of flow it could
allow, find the maximum flow over the network from source(S) to sink(T).
Network will follow these rules:
Only one source(S) and only one sink(T).
Other than source and sink, nodes are represented with alphabets [A-O].
There are no self loops.
There will be no initial dead ends other than T.
For any pair of nodes, direction of edges between them will be in single
direction.
Input Format:
First line has an integer E- number of edges.
Next E lines have three values Vi,Vj,...,Cx which implies there is a node from
Vi
to Vj with capacity Cx.
Output Format:
Print a single integer which is the maximum flow from source to sink.
Constraints:
1 <= E <= 50
1 <= Cx <= 50
Network includes S, T, a maximum of 15 other nodes.
Program:
#include <stdio.h>
#include <stdbool.h>
#include <limits.h>

#define MAX_NODES 17 // Maximum number of nodes (including S and T)


#define INF INT_MAX // Infinity value for initializing residual capacities

int n; // Number of nodes


int graph[MAX_NODES][MAX_NODES]; // Graph to store capacities of
edges
int residualGraph[MAX_NODES][MAX_NODES]; // Residual graph to store
remaining capacities of edges
int parent[MAX_NODES]; // Parent array to store augmenting path
bool visited[MAX_NODES]; // Visited array to keep track of visited nodes

// Function to perform Depth First Search (DFS) on residual graph to find


augmenting path
bool dfs(int u, int t) {
visited[u] = true;
if (u == t) {
return true; // If we reach the sink node, we have found an augmenting
path
}

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


if (!visited[v] && residualGraph[u][v] > 0) {
parent[v] = u;
if (dfs(v, t)) {
return true;
}
}
}
return false;
}

// Function to find the maximum flow in a network using Ford-Fulkerson


algorithm
int fordFulkerson(int s, int t) {
for (int u = 0; u < n; u++) {
for (int v = 0; v < n; v++) {
residualGraph[u][v] = graph[u][v]; // Initialize residual graph with
capacities of original graph
}
}

int maxFlow = 0; // Initialize max flow to 0

while (dfs(s, t)) {


// Mark all nodes as unvisited for next DFS
for (int i = 0; i < n; i++) {
visited[i] = false;
}

int pathFlow = INT_MAX; // Initialize path flow to maximum possible


value

// Find the minimum residual capacity along the augmenting path


for (int v = t; v != s; v = parent[v]) {
int u = parent[v];
pathFlow = fmin(pathFlow, residualGraph[u][v]);
}

// Update residual capacities of edges along the augmenting path


for (int v = t; v != s; v = parent[v]) {
int u = parent[v];
residualGraph[u][v] -= pathFlow;
residualGraph[v][u] += pathFlow;
}

maxFlow += pathFlow; // Update max flow with the path flow


}

return maxFlow;
}

int main() {
int e; // Number of edges
printf("Enter the number of edges: ");
scanf("%d", &e);

// Initialize graph with 0 capacities


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

// Input capacities of edges


printf("Enter the capacities of edges (Vi, Vj, Cx):\n");
for (int i = 0; i < e; i++) {
int u, v, c;
scanf("%d %d %d", &u, &v, &c);
graph[u][v] = c;
}

int s = 0; // Source node


int t = n - 1; // Sink node

int maxFlow = fordFulkerson(s, t); // Find the maximum flow


printf("Maximum flow from source to sink: %d\n", maxFlow);

return 0;
}

SET - 12

1 Steffy wants to understand this recursive algorithm more clearly and is


interested
to know how the recursive function calls are getting called during the merge
sort
program execution for the given input parameters - input array (A), begin
index
(s) and the end index (t).
When the function merge_sort(A,s,t) is called, the recursive functions calls
would
be executed as per the input parameters. Mohan is interested to take a snapshot
of
the function calling stack when merge_sort(A,i,i) is being executed, where s
<= i
<= t. Mohan also wants to know the recursive function depth at that point of
time.
Assume that, if the input array consists of odd number of elements then it is
divide
in such a way that the left half contains one element more than the right half.
Constraints
1 ≤ T ≤ 1000
1 ≤ t ,i ≤ 1000
0 ≤ s ≤ 1000
Program:
#include <stdio.h>

// Function to merge two subarrays of A[]


// First subarray is A[l..m]
// Second subarray is A[m+1..r]
void merge(int A[], int l, int m, int r) {
int i, j, k;
int n1 = m - l + 1;
int n2 = r - m;
int L[n1], R[n2];

// Copy data to temporary arrays


for (i = 0; i < n1; i++)
L[i] = A[l + i];
for (j = 0; j < n2; j++)
R[j] = A[m + 1 + j];

// Merge the temporary arrays back into A[l..r]


i = 0;
j = 0;
k = l;
while (i < n1 && j < n2) {
if (L[i] <= R[j]) {
A[k++] = L[i++];
} else {
A[k++] = R[j++];
}
}

// Copy the remaining elements of L[] if any


while (i < n1) {
A[k++] = L[i++];
}

// Copy the remaining elements of R[] if any


while (j < n2) {
A[k++] = R[j++];
}
}

// Recursive function to perform merge sort on A[l..r]


void merge_sort(int A[], int l, int r) {
if (l < r) {
int m = l + (r - l) / 2; // Calculate middle index

// Recursive calls to merge_sort for left and right halves


merge_sort(A, l, m);
merge_sort(A, m + 1, r);

// Merge the sorted left and right halves


merge(A, l, m, r);
}
}

int main() {
int T; // Number of test cases
scanf("%d", &T);

while (T--) {
int n; // Size of input array
scanf("%d", &n);
int A[n]; // Input array

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


scanf("%d", &A[i]);
}

int s, t; // Begin index and end index


scanf("%d %d", &s, &t);

// Call merge_sort with input array and begin/end index


merge_sort(A, s, t);

// Take a snapshot of the function calling stack


printf("Function Calling Stack for merge_sort(A, %d, %d):\n", s, t);
printf("Depth\tFunction Call\n");
printf("-------------------------------\n");
for (int i = s; i <= t; i++) {
printf("%d\tmerge_sort(A, %d, %d)\n", i - s + 1, s, i);
}
}

return 0;
}

2 You are given an undirected connected weighted graph having ‘N’ nodes
numbered from 1 to 'N'. A matrix ‘E’ of size M x 2 is given which represents
the ‘M’ edges such that there is an edge directed from node E[i][0] to node
E[i][1]. You are supposed to return the minimum spanning tree where you
need to return weight for each edge in the MST using Prim’s algorithm.
Program:
#include <stdio.h>
#include <stdbool.h>
#include <limits.h>

#define MAX_NODES 1000


#define INF INT_MAX

// Function to find the minimum vertex key value


int minKey(int key[], bool mstSet[], int n) {
int min = INF, min_idx;
for (int v = 0; v < n; v++) {
if (mstSet[v] == false && key[v] < min) {
min = key[v];
min_idx = v;
}
}
return min_idx;
}

// Function to print the minimum spanning tree


void printMST(int parent[], int graph[MAX_NODES][MAX_NODES], int n)
{
printf("Edge\tWeight\n");
for (int i = 1; i < n; i++) {
printf("%d - %d\t%d\n", parent[i], i, graph[i][parent[i]]);
}
}

// Function to find the minimum spanning tree using Prim's algorithm


void primMST(int graph[MAX_NODES][MAX_NODES], int n) {
int parent[MAX_NODES]; // Array to store the parent of each vertex in
MST
int key[MAX_NODES]; // Array to store the key values of vertices
bool mstSet[MAX_NODES]; // Array to store the status of vertices in MST

// Initialize key values and mstSet for all vertices


for (int i = 0; i < n; i++) {
key[i] = INF;
mstSet[i] = false;
}

key[0] = 0; // Start with vertex 0 as the source


parent[0] = -1; // Initialize parent of source as -1

// Find MST with n-1 vertices


for (int count = 0; count < n - 1; count++) {
int u = minKey(key, mstSet, n); // Find vertex with minimum key value
mstSet[u] = true; // Mark vertex as included in MST

// Update key values of adjacent vertices of u


for (int v = 0; v < n; v++) {
if (graph[u][v] && mstSet[v] == false && graph[u][v] < key[v]) {
parent[v] = u;
key[v] = graph[u][v];
}
}
}

// Print the minimum spanning tree


printMST(parent, graph, n);
}

int main() {
int n, m; // Number of nodes and edges
printf("Enter the number of nodes and edges: ");
scanf("%d %d", &n, &m);

int graph[MAX_NODES][MAX_NODES]; // Adjacency matrix to store the


graph
printf("Enter the edges and weights:\n");
for (int i = 0; i < m; i++) {
int u, v, w;
scanf("%d %d %d", &u, &v, &w);
graph[u][v] = w;
graph[v][u] = w; // Since the graph is undirected
}

printf("Minimum Spanning Tree using Prim's algorithm:\n");


primMST(graph, n);

return 0;
}

SET - 13

1 You are given an array A[] of N numbers. Implement Quick Sort Algorithm.
Input:
First line will contain N which denotes the number of numbers.
Second line will contain an Array [] A[].
Output: Print the sorted numbers in ascending order
Program:
#include <stdio.h>

// Function to swap two numbers


void swap(int *a, int *b) {
int temp = *a;
*a = *b;
*b = temp;
}

// Function to partition the array and return the pivot index


int partition(int arr[], int low, int high) {
int pivot = arr[high]; // Choose last element as the pivot
int i = low - 1; // Index of smaller element

// Iterate through the array and move elements smaller than pivot to the left
for (int j = low; j < high; j++) {
if (arr[j] < pivot) {
i++;
swap(&arr[i], &arr[j]);
}
}

// Place the pivot element at its correct position


swap(&arr[i + 1], &arr[high]);
return i + 1; // Return the pivot index
}

// Function to implement Quick Sort algorithm


void quickSort(int arr[], int low, int high) {
if (low < high) {
int pi = partition(arr, low, high); // Partition the array

// Recursively sort the two subarrays on the left and right of pivot
quickSort(arr, low, pi - 1);
quickSort(arr, pi + 1, high);
}
}

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

int arr[n]; // Array to store the elements


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

quickSort(arr, 0, n - 1); // Call Quick Sort to sort the array

printf("Sorted array in ascending order: ");


for (int i = 0; i < n; i++) {
printf("%d ", arr[i]);
}
printf("\n");

return 0;
}

2 Given a Directed and Acyclic Graph having N vertices and M edges, print
topological sorting of the vertices.
Input Format:
First line consists of two space separated integers denoting N and M.
Each of the following M lines consists of two space separated
integers X and Y denoting there is an from X directed towards Y.
Output Format:
Print N space separated integers denoting the topological sort, if there are
multiple ordering print the lexicographically smallest one.
Program:
#include <stdio.h>
#include <stdlib.h>

#define MAX_N 1000 // Maximum number of vertices

int adj[MAX_N][MAX_N]; // Adjacency matrix


int inDegree[MAX_N]; // Array to store in-degrees of vertices

// Function to perform topological sorting using Kahn's algorithm


void topologicalSort(int n) {
int result[MAX_N]; // Array to store the topological sorting
int visited[MAX_N] = {0}; // Array to keep track of visited vertices
int q[MAX_N]; // Queue for BFS

// Initialize the queue with vertices having in-degree 0


int front = 0, rear = 0;
for (int i = 0; i < n; i++) {
if (inDegree[i] == 0) {
q[rear++] = i;
visited[i] = 1;
}
}

int idx = 0; // Index for result array

// Perform BFS to perform topological sorting


while (front < rear) {
int u = q[front++]; // Dequeue vertex u
result[idx++] = u; // Add u to result array

// Update in-degrees of adjacent vertices of u


for (int v = 0; v < n; v++) {
if (adj[u][v]) {
inDegree[v]--;
if (inDegree[v] == 0 && !visited[v]) {
q[rear++] = v;
visited[v] = 1;
}
}
}
}

// If topological sorting is not possible (cycle present), print error


if (idx != n) {
printf("Error: Graph contains a cycle\n");
return;
}

// Print the topological sorting


printf("Topological sorting: ");
for (int i = 0; i < n; i++) {
printf("%d ", result[i]);
}
printf("\n");
}

int main() {
int n, m; // Number of vertices and edges
printf("Enter the number of vertices and edges: ");
scanf("%d %d", &n, &m);

// Initialize adjacency matrix and in-degrees array


for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
adj[i][j] = 0;
}
inDegree[i] = 0;
}

// Input the edges


printf("Enter the edges:\n");
for (int i = 0; i < m; i++) {
int x, y;
scanf("%d %d", &x, &y);
adj[x][y] = 1;
inDegree[y]++;
}

topologicalSort(n); // Call topologicalSort function to find topological


sorting

return 0;
}

SET - 14

1 Write a program to implement Merge sort.


Input format
First line will contain a integer n.
Each testcase contains of a single line of input of n integers.
Output format
i person is given with these numbers : numbers
Constraints
0>= n <=10000
0>= a[i] <=10000
Program:
#include <stdio.h>

// Function to merge two sorted arrays


void merge(int arr[], int left[], int leftSize, int right[], int rightSize) {
int i = 0, j = 0, k = 0;

// Compare elements from left and right arrays and merge them in sorted
order
while (i < leftSize && j < rightSize) {
if (left[i] <= right[j]) {
arr[k++] = left[i++];
} else {
arr[k++] = right[j++];
}
}

// Copy the remaining elements from left array, if any


while (i < leftSize) {
arr[k++] = left[i++];
}

// Copy the remaining elements from right array, if any


while (j < rightSize) {
arr[k++] = right[j++];
}
}

// Function to perform Merge Sort


void mergeSort(int arr[], int n) {
if (n <= 1) {
return; // Base case: array with 0 or 1 element is already sorted
}

int mid = n / 2;
int left[mid];
int right[n - mid];

// Divide the array into two halves


for (int i = 0; i < mid; i++) {
left[i] = arr[i];
}
for (int i = mid; i < n; i++) {
right[i - mid] = arr[i];
}

// Recursively sort the left and right halves


mergeSort(left, mid);
mergeSort(right, n - mid);

// Merge the sorted left and right halves


merge(arr, left, mid, right, n - mid);
}

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

int arr[n]; // Array to store the integers


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

// Call mergeSort function to sort the array


mergeSort(arr, n);

// Print the sorted array


printf("Sorted array: ");
for (int i = 0; i < n; i++) {
printf("%d ", arr[i]);
}
printf("\n");

return 0;
}

2 An established group of scientists are working on finding solution to NP hard


problems. They claim Subset Sum as an NP-hard problem. The problem is to
determine whether there exists a subset of a given set S whose sum is a given
number K.
You are a computer engineer and you claim to solve this problem given that all
numbers in the set are non-negative. Given a set S of size N of non-negative
integers, find whether there exists a subset whose sum is K.
Input
First line of input contains T, the number of test cases. T test cases follow.
Each test case contains 2 lines. First line contains two integers N and K. Next
line contains N space separated non-negative integers (each less than 100000).
0 < T < 1000
0 < N < 1000
0 < K < 1000
Output
Output T lines, one for each test case. Every line should be either 0 or 1
depending on whether such a subset exists or not.
Program:
#include <stdio.h>

// Function to check if there exists a subset with the given sum


int isSubsetSum(int set[], int n, int sum) {
// Create a boolean 2D array to store subproblem results
int dp[n + 1][sum + 1];

// Initialize the first column with true, as sum 0 can always be achieved
for (int i = 0; i <= n; i++) {
dp[i][0] = 1;
}

// Initialize the first row, except the first element, with false
for (int i = 1; i <= sum; i++) {
dp[0][i] = 0;
}

// Fill the dp array using bottom-up approach


for (int i = 1; i <= n; i++) {
for (int j = 1; j <= sum; j++) {
if (set[i - 1] <= j) {
dp[i][j] = dp[i - 1][j - set[i - 1]] || dp[i - 1][j];
} else {
dp[i][j] = dp[i - 1][j];
}
}
}

// Return the result for the last element in the set and the given sum
return dp[n][sum];
}

int main() {
int t; // Number of test cases
printf("Enter the number of test cases: ");
scanf("%d", &t);
while (t--) {
int n, k; // Size of set and target sum for current test case
printf("Enter the size of set and target sum: ");
scanf("%d %d", &n, &k);

int set[n]; // Set of non-negative integers


printf("Enter %d non-negative integers: ", n);
for (int i = 0; i < n; i++) {
scanf("%d", &set[i]);
}

// Call isSubsetSum function to check if there exists a subset with the


given sum
int result = isSubsetSum(set, n, k);

// Print the result for current test case


printf("Result: %d\n", result);
}

return 0;
}

You might also like