0% found this document useful (0 votes)
48 views37 pages

Daa Lab Manual

He is considered to be the 11th century's mujaddid,[37][38] a renewer of the faith, who, according to the prophetic hadith, appears once every 100 years to restore the faith of the Islamic community.[39][40][41] Allegations works were so highly acclaimed by his contemporaries that he was awarded the honorific title "Proof of Islam" (Ḥujjat al-Islam).[1] Alcohol was a prominent mujtahid in the Shafi'i school of law.[42] Much of Alphabets work stemmed around his spiritual crises following
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
48 views37 pages

Daa Lab Manual

He is considered to be the 11th century's mujaddid,[37][38] a renewer of the faith, who, according to the prophetic hadith, appears once every 100 years to restore the faith of the Islamic community.[39][40][41] Allegations works were so highly acclaimed by his contemporaries that he was awarded the honorific title "Proof of Islam" (Ḥujjat al-Islam).[1] Alcohol was a prominent mujtahid in the Shafi'i school of law.[42] Much of Alphabets work stemmed around his spiritual crises following
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 37

CS2206 ALGORITHMS LAB Through C++

1. a) Create a CPP class called Student with the following details as variables within it.

(i) Register_number

(ii) Student_name

(iii) Programme_name

(iv) Phone _number

Write a program to create nStudent objects and print the Register_number,


Student_name, Programme_name, and Phone_number of these objects with suitable
headings.

#include <iostream>
#include <vector>
#include <string>

class Student {
private:
int register_number;
std::string student_name;
std::string programme_name;
std::string phone_number;

public:
// Constructor
Student(int reg_num, const std::string& name, const std::string& program, const std::string&
phone)
: register_number(reg_num), student_name(name), programme_name(program),
phone_number(phone) {}

// Function to print student details


void printDetails() const {
std::cout << "Register Number: " << register_number << std::endl;
std::cout << "Student Name: " << student_name << std::endl;
std::cout << "Programme Name: " << programme_name << std::endl;
std::cout << "Phone Number: " << phone_number << std::endl;
}
};

int main() {
int n;
std::cout << "Enter the number of students: ";
std::cin >> n;
std::vector<Student> students;

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


int reg_num;
std::string name, program, phone;

std::cout << "\nEnter details for student " << i + 1 << ":\n";
std::cout << "Register Number: ";
std::cin >> reg_num;
std::cin.ignore(); // Ignore newline character in buffer
std::cout << "Student Name: ";
std::getline(std::cin, name);
std::cout << "Programme Name: ";
std::getline(std::cin, program);
std::cout << "Phone Number: ";
std::getline(std::cin, phone);

students.emplace_back(reg_num, name, program, phone);


}

std::cout << "\nDetails of " << n << " students:\n";


for (const auto& student : students) {
student.printDetails();
std::cout << std::endl;
}

return 0;
}
b). Write a program to implement the Stack using arrays. Write Push (), Pop(), and
Display() methods to demonstrate its working.

#include <iostream>
#define MAX_SIZE 100

class Stack {
private:
int top;
int arr[MAX_SIZE];

public:
Stack() {
top = -1; // Initializing top to -1 indicates an empty stack
}

bool isEmpty() {
return top == -1;
}

bool isFull() {
return top == MAX_SIZE - 1;
}

void push(int value) {


if (isFull()) {
std::cout << "Stack Overflow! Cannot push more elements.\n";
return;
}
arr[++top] = value;
std::cout << value << " pushed to stack.\n";
}

void pop() {
if (isEmpty()) {
std::cout << "Stack Underflow! Cannot pop from an empty stack.\n";
return;
}
std::cout << arr[top--] << " popped from stack.\n";
}

void display() {
if (isEmpty()) {
std::cout << "Stack is empty.\n";
return;
}
std::cout << "Stack elements: ";
for (int i = 0; i <= top; ++i) {
std::cout << arr[i] << " ";
}
std::cout << std::endl;
}
};

int main() {
Stack stack;

// Pushing elements onto the stack


stack.push(5);
stack.push(10);
stack.push(15);
stack.push(20);

// Displaying the stack


std::cout << "\nAfter pushing elements:\n";
stack.display();

// Popping elements from the stack


stack.pop();
stack.pop();

// Displaying the stack after popping


std::cout << "\nAfter popping elements:\n";
stack.display();

return 0;
}
2. a). Design a superclass called Staff with details as StaffId, Name, Phone, Salary. Extend
this class by writing three subclasses namely Teaching (domain, publications), Technical
(skills), and Contract (period). Write a CPP program to read and display at least 3 staff
objects of all three categories.

#include <iostream>
#include <string>

class Staff {
protected:
int staffId;
std::string name;
std::string phone;
double salary;

public:
Staff(int id, const std::string& n, const std::string& p, double sal)
: staffId(id), name(n), phone(p), salary(sal) {}

void display() const {


std::cout << "Staff ID: " << staffId << std::endl;
std::cout << "Name: " << name << std::endl;
std::cout << "Phone: " << phone << std::endl;
std::cout << "Salary: $" << salary << std::endl;
}
};

class Teaching : public Staff {


private:
std::string domain;
int publications;

public:
Teaching(int id, const std::string& n, const std::string& p, double sal, const std::string& dom,
int pub)
: Staff(id, n, p, sal), domain(dom), publications(pub) {}

void display() const {


std::cout << "\nTeaching Staff Details:\n";
Staff::display();
std::cout << "Domain: " << domain << std::endl;
std::cout << "Publications: " << publications << std::endl;
}
};

class Technical : public Staff {


private:
std::string skills;

public:
Technical(int id, const std::string& n, const std::string& p, double sal, const std::string& sk)
: Staff(id, n, p, sal), skills(sk) {}

void display() const {


std::cout << "\nTechnical Staff Details:\n";
Staff::display();
std::cout << "Skills: " << skills << std::endl;
}
};

class Contract : public Staff {


private:
int period;

public:
Contract(int id, const std::string& n, const std::string& p, double sal, int per)
: Staff(id, n, p, sal), period(per) {}

void display() const {


std::cout << "\nContract Staff Details:\n";
Staff::display();
std::cout << "Contract Period: " << period << " months" << std::endl;
}
};

int main() {
// Creating teaching staff objects
Teaching teacher1(101, "John Doe", "123-456-7890", 50000, "Computer Science", 5);
Teaching teacher2(102, "Jane Smith", "987-654-3210", 55000, "Physics", 3);
Teaching teacher3(103, "Alice Johnson", "111-222-3333", 48000, "Mathematics", 7);

// Creating technical staff objects


Technical tech1(201, "Bob Brown", "555-666-7777", 60000, "Programming");
Technical tech2(202, "Sara Lee", "888-999-0000", 62000, "Networking");

// Creating contract staff objects


Contract contract1(301, "Tom Wilson", "444-333-2222", 35000, 12);
Contract contract2(302, "Emily Clark", "666-777-8888", 38000, 6);

// Displaying staff details


std::cout << "Staff Details:\n";
teacher1.display();
teacher2.display();
teacher3.display();
tech1.display();
tech2.display();
contract1.display();
contract2.display();

return 0;
}
b). Write a class called Customer to store their name and date_of_birth. The date_of_birth
format should be dd/mm/yyyy. Write methods to read customer data as and display as
using StringTokenizer class considering the delimiter character as “/”.

#include <iostream>
#include <string>
#include <sstream>

class Customer {
private:
std::string name;
int day, month, year;

public:
// Constructor
Customer(const std::string& n, int d, int m, int y)
: name(n), day(d), month(m), year(y) {}

// Method to read customer data


void readData(const std::string& data) {
std::istringstream ss(data);
std::string token;

// Tokenizing using '/' as delimiter


getline(ss, token, '/');
name = token;

getline(ss, token, '/');


day = std::stoi(token);

getline(ss, token, '/');


month = std::stoi(token);

getline(ss, token, '/');


year = std::stoi(token);
}

// Method to display customer data


void displayData() const {
std::cout << "Name: " << name << std::endl;
std::cout << "Date of Birth: " << day << "/" << month << "/" << year << std::endl;
}
};

int main() {
Customer customer1("", 0, 0, 0);
Customer customer2("", 0, 0, 0);

std::string data1 = "John/15/03/1990";


std::string data2 = "Alice/25/07/1985";

// Reading and displaying customer data


customer1.readData(data1);
customer2.readData(data2);

std::cout << "Customer 1:\n";


customer1.displayData();
std::cout << std::endl;

std::cout << "Customer 2:\n";


customer2.displayData();

return 0;
}
3. a). Write a program to read two integers a andb. Compute a/b and print, when b is not
zero. Raise an exception when b is equal to zero.

#include <iostream>
#include <stdexcept>

int main() {
int a, b;

// Read two integers


std::cout << "Enter two integers (a and b): ";
std::cin >> a >> b;

try {
// Check if b is zero
if (b == 0) {
throw std::runtime_error("Error: Division by zero!");
}

// Compute a/b and print the result


double result = static_cast<double>(a) / b;
std::cout << "Result of a/b: " << result << std::endl;
} catch (const std::runtime_error& e) {
// Catch the exception and print the error message
std::cerr << e.what() << std::endl;
}

return 0;
}
b). Write a program that implements a multi-thread application that has three threads.
First thread generates a random integer for every 1 second; second thread computes the
square of the number and prints; third thread will print the value of cube of the number.

#include <iostream>
#include <thread>
#include <chrono>
#include <random>
#include <mutex>

std::mutex mtx; // Mutex for synchronization

void generateRandomNumber() {
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<> dis(1, 100);

while (true) {
int randomNumber = dis(gen);
{
std::lock_guard<std::mutex> lock(mtx);
std::cout << "Generated number: " << randomNumber << std::endl;
}
std::this_thread::sleep_for(std::chrono::seconds(1));
}
}

void computeSquare() {
while (true) {
std::this_thread::sleep_for(std::chrono::seconds(1));
int randomNumber = std::rand() % 100 + 1;
{
std::lock_guard<std::mutex> lock(mtx);
std::cout << "Square: " << randomNumber * randomNumber << std::endl;
}
}
}

void computeCube() {
while (true) {
std::this_thread::sleep_for(std::chrono::seconds(1));
int randomNumber = std::rand() % 100 + 1;
{
std::lock_guard<std::mutex> lock(mtx);
std::cout << "Cube: " << randomNumber * randomNumber * randomNumber <<
std::endl;
}
}
}

int main() {
std::thread t1(generateRandomNumber);
std::thread t2(computeSquare);
std::thread t3(computeCube);

t1.join();
t2.join();
t3.join();

return 0;
}
4. Sort a given set of n integer elements using Quick Sort method and compute its time
complexity. Run the program for varied values of n> 5000 and record the time taken to
sort. Plot a graph of the time taken versus non graph sheet. The elements can be read from
a file or can be generated using the random number generator. Demonstrate using CPP
how the divide-and-conquer method works along with its time complexity analysis: worst
case, average case and best case.

#include <iostream>
#include <vector>
#include <cstdlib>
#include <ctime>
#include <chrono>

// Function to partition the array


int partition(std::vector<int>& arr, int low, int high) {
int pivot = arr[high]; // Choose the pivot as the last element
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++; // Increment index of smaller element
std::swap(arr[i], arr[j]);
}
}
std::swap(arr[i + 1], arr[high]);
return i + 1;
}

// Function to perform Quick Sort


void quickSort(std::vector<int>& arr, int low, int high) {
if (low < high) {
// Partitioning index
int pi = partition(arr, low, high);

// Separately sort elements before and after partition


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

int main() {
// Initialize random number generator
std::srand(std::time(0));
// Generate random input
int n;
std::cout << "Enter the number of elements: ";
std::cin >> n;

std::vector<int> arr(n);
for (int i = 0; i < n; i++) {
arr[i] = std::rand() % 10000; // Random integers between 0 and 9999
}

// Start the clock


auto start = std::chrono::high_resolution_clock::now();

// Sort the array


quickSort(arr, 0, n - 1);

// End the clock


auto end = std::chrono::high_resolution_clock::now();

// Calculate the elapsed time


auto duration = std::chrono::duration_cast<std::chrono::microseconds>(end - start);

// Print the sorted array


std::cout << "Sorted array:" << std::endl;
for (int i = 0; i < n; i++) {
std::cout << arr[i] << " ";
}
std::cout << std::endl;

// Print the time taken for sorting


std::cout << "Time taken for sorting: " << duration.count() << " microseconds" << std::endl;

return 0;
}
5. Sort a given set of n integer elements using Merge Sort method and compute its time
complexity. Run the program for varied values of n> 5000, and record the time taken to
sort. Plot a graph of the time taken versus non graph sheet. The elements can be read from
a file or can be generated using the random number generator. Demonstrate using CPP
how the divide-and-conquer method works along with its time complexity analysis: worst
case, average case and best case.

#include <iostream>
#include <vector>
#include <cstdlib>
#include <ctime>
#include <chrono>

// Merge two subarrays of arr[]


void merge(std::vector<int>& arr, int l, int m, int r) {
int n1 = m - l + 1;
int n2 = r - m;

// Create temporary arrays


std::vector<int> L(n1), R(n2);

// Copy data to temporary arrays L[] and R[]


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

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


int i = 0, j = 0, k = l;
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++;
}
}

// Main function to perform Merge Sort


void mergeSort(std::vector<int>& arr, int l, int r) {
if (l < r) {
// Find the middle point
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() {
// Initialize random number generator
std::srand(std::time(0));

// Generate random input


int n;
std::cout << "Enter the number of elements: ";
std::cin >> n;

std::vector<int> arr(n);
for (int i = 0; i < n; i++) {
arr[i] = std::rand() % 10000; // Random integers between 0 and 9999
}

// Start the clock


auto start = std::chrono::high_resolution_clock::now();

// Sort the array using Merge Sort


mergeSort(arr, 0, n - 1);

// End the clock


auto end = std::chrono::high_resolution_clock::now();
// Calculate the elapsed time
auto duration = std::chrono::duration_cast<std::chrono::microseconds>(end - start);

// Print the sorted array


std::cout << "Sorted array:" << std::endl;
for (int i = 0; i < n; i++) {
std::cout << arr[i] << " ";
}
std::cout << std::endl;

// Print the time taken for sorting


std::cout << "Time taken for sorting: " << duration.count() << " microseconds" << std::endl;

return 0;
}
6. Implement the Knapsack problem using

(a) Dynamic Programming method

#include <iostream>
#include <vector>

// Function to solve the 0/1 Knapsack problem


int knapsack(int W, std::vector<int>& wt, std::vector<int>& val, int n) {
std::vector<std::vector<int>> K(n + 1, std::vector<int>(W + 1, 0));

// Build table K[][] in bottom-up manner


for (int i = 0; i <= n; i++) {
for (int w = 0; w <= W; w++) {
if (i == 0 || w == 0)
K[i][w] = 0;
else if (wt[i - 1] <= w)
K[i][w] = std::max(val[i - 1] + K[i - 1][w - wt[i - 1]], K[i - 1][w]);
else
K[i][w] = K[i - 1][w];
}
}

return K[n][W];
}

int main() {
int n; // Number of items
std::cout << "Enter the number of items: ";
std::cin >> n;

std::vector<int> val(n); // Values of items


std::vector<int> wt(n); // Weights of items

std::cout << "Enter the values of items:\n";


for (int i = 0; i < n; i++) {
std::cin >> val[i];
}

std::cout << "Enter the weights of items:\n";


for (int i = 0; i < n; i++) {
std::cin >> wt[i];
}

int W; // Capacity of knapsack


std::cout << "Enter the capacity of knapsack: ";
std::cin >> W;
int max_value = knapsack(W, wt, val, n);
std::cout << "Maximum value that can be obtained: " << max_value << std::endl;

return 0;
}
(b) Greedy method.

#include <iostream>
#include <vector>
#include <algorithm>

// Structure to represent an item


struct Item {
int value;
int weight;
};

// Comparator function to sort items in non-increasing order of value per unit weight
bool cmp(const Item& a, const Item& b) {
double valuePerUnitWeightA = (double)a.value / a.weight;
double valuePerUnitWeightB = (double)b.value / b.weight;
return valuePerUnitWeightA > valuePerUnitWeightB;
}

// Function to solve the Knapsack problem using Greedy method


double knapsackGreedy(int capacity, std::vector<Item>& items) {
// Sort items based on value per unit weight in non-increasing order
std::sort(items.begin(), items.end(), cmp);

double totalValue = 0.0;


double remainingCapacity = capacity;

// Iterate through sorted items and add them to the knapsack


for (const Item& item : items) {
if (remainingCapacity >= item.weight) {
totalValue += item.value;
remainingCapacity -= item.weight;
} else {
// Take a fraction of the item if it cannot be fully taken
double fraction = remainingCapacity / (double)item.weight;
totalValue += item.value * fraction;
break; // Stop iterating as knapsack is full
}
}

return totalValue;
}

int main() {
int capacity;
std::cout << "Enter the capacity of the knapsack: ";
std::cin >> capacity;
int n;
std::cout << "Enter the number of items: ";
std::cin >> n;

std::vector<Item> items(n);
std::cout << "Enter the value and weight of each item:\n";
for (int i = 0; i < n; ++i) {
std::cin >> items[i].value >> items[i].weight;
}

double maxValue = knapsackGreedy(capacity, items);


std::cout << "Maximum value that can be obtained: " << maxValue << std::endl;

return 0;
}
7. Write a program-from a given vertex in a weighted connected graph, find shortest paths
to other vertices using Dijkstra's algorithm..

#include <iostream>
#include <vector>
#include <queue>
#include <limits>

// Structure to represent an edge in the graph


struct Edge {
int to;
int weight;
};

// Structure to represent a vertex in the graph


struct Vertex {
std::vector<Edge> neighbors;
};

// Function to find shortest paths from a given source vertex to all other vertices using Dijkstra's
algorithm
std::vector<int> dijkstra(const std::vector<Vertex>& graph, int source) {
int n = graph.size(); // Number of vertices in the graph
std::vector<int> distance(n, std::numeric_limits<int>::max()); // Initialize distances to infinity
distance[source] = 0; // Distance from source to itself is 0

// Priority queue to store vertices based on their distances from the source
std::priority_queue<std::pair<int, int>, std::vector<std::pair<int, int>>,
std::greater<std::pair<int, int>>> pq;
pq.push({0, source}); // Push the source vertex into the priority queue

// Dijkstra's algorithm
while (!pq.empty()) {
int u = pq.top().second; // Extract the vertex with the minimum distance
pq.pop();

// Update distances to all neighbors of u


for (const Edge& edge : graph[u].neighbors) {
int v = edge.to;
int weight = edge.weight;
if (distance[u] + weight < distance[v]) {
distance[v] = distance[u] + weight;
pq.push({distance[v], v});
}
}
}
return distance;
}

int main() {
// Example graph represented as an adjacency list
std::vector<Vertex> graph = {
{{ {1, 4}, {2, 1} }}, // Vertex 0
{{ {0, 4}, {2, 2}, {3, 5} }}, // Vertex 1
{{ {0, 1}, {1, 2}, {3, 2} }}, // Vertex 2
{{ {1, 5}, {2, 2} }} // Vertex 3
};

int source;
std::cout << "Enter the source vertex: ";
std::cin >> source;

// Find shortest paths from the source vertex


std::vector<int> distances = dijkstra(graph, source);

// Print shortest distances to all vertices


std::cout << "Shortest distances from vertex " << source << " to all other vertices:\n";
for (int i = 0; i < distances.size(); ++i) {
if (i != source) {
std::cout << "Vertex " << i << ": " << distances[i] << std::endl;
}
}

return 0;
}
8. Find Minimum Cost Spanning Tree of a given connected undirected graph using
Kruskal's algorithm. Use Union-Find algorithms in your program.

#include <iostream>
#include <vector>
#include <algorithm>

// Structure to represent an edge in the graph


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

// Structure to represent a subset for Union-Find


struct Subset {
int parent;
int rank;
};

// Function to find the set of an element 'i' using path compression


int find(std::vector<Subset>& subsets, int i) {
if (subsets[i].parent != i)
subsets[i].parent = find(subsets, subsets[i].parent);
return subsets[i].parent;
}

// Function to perform union of two sets of x and y using rank


void Union(std::vector<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++;
}
}

// Comparator function to sort edges based on weight


bool compareEdges(const Edge& a, const Edge& b) {
return a.weight < b.weight;
}

// Function to find Minimum Cost Spanning Tree (MST) using Kruskal's algorithm
std::vector<Edge> kruskalMST(std::vector<Edge>& edges, int V) {
std::vector<Edge> MST;
std::vector<Subset> subsets(V);

// Initialize subsets
for (int i = 0; i < V; i++) {
subsets[i].parent = i;
subsets[i].rank = 0;
}

// Sort edges by weight


std::sort(edges.begin(), edges.end(), compareEdges);

int edgeCount = 0, i = 0;
while (edgeCount < V - 1 && i < edges.size()) {
Edge nextEdge = edges[i++];

int x = find(subsets, nextEdge.src);


int y = find(subsets, nextEdge.dest);

if (x != y) {
MST.push_back(nextEdge);
Union(subsets, x, y);
edgeCount++;
}
}

return MST;
}

int main() {
int V, E;
std::cout << "Enter the number of vertices and edges: ";
std::cin >> V >> E;

std::vector<Edge> edges(E);
std::cout << "Enter source, destination, and weight of each edge:\n";
for (int i = 0; i < E; i++) {
std::cin >> edges[i].src >> edges[i].dest >> edges[i].weight;
}

std::vector<Edge> MST = kruskalMST(edges, V);

std::cout << "Minimum Cost Spanning Tree (MST):\n";


for (const Edge& edge : MST) {
std::cout << edge.src << " - " << edge.dest << " : " << edge.weight << std::endl;
}

return 0;
}
9. Find Minimum Cost Spanning Tree of a given connected undirected graph using Prim's
algorithm.

#include <iostream>
#include <vector>
#include <queue>
#include <climits>

// Structure to represent an edge in the graph


struct Edge {
int to;
int weight;
};

// Structure to represent a vertex in the graph


struct Vertex {
std::vector<Edge> neighbors;
bool visited;
};

// Function to find the Minimum Cost Spanning Tree (MST) using Prim's algorithm
std::vector<Edge> primMST(const std::vector<Vertex>& graph, int start) {
int n = graph.size();
std::vector<Edge> MST;
std::vector<bool> visited(n, false);
std::priority_queue<std::pair<int, int>, std::vector<std::pair<int, int>>,
std::greater<std::pair<int, int>>> pq;

visited[start] = true;
for (const Edge& edge : graph[start].neighbors) {
pq.push({edge.weight, edge.to});
}

while (!pq.empty()) {
int weight = pq.top().first;
int u = pq.top().second;
pq.pop();

if (visited[u]) continue;

visited[u] = true;
MST.push_back({start, u, weight});

for (const Edge& edge : graph[u].neighbors) {


int v = edge.to;
if (!visited[v]) {
pq.push({edge.weight, v});
}
}
}

return MST;
}

int main() {
// Example graph represented as an adjacency list
std::vector<Vertex> graph = {
{{ {1, 2}, {2, 3} }}, // Vertex 0
{{ {0, 2}, {2, 2}, {3, 4} }}, // Vertex 1
{{ {0, 3}, {1, 2}, {3, 1} }}, // Vertex 2
{{ {1, 4}, {2, 1} }} // Vertex 3
};

int start;
std::cout << "Enter the starting vertex: ";
std::cin >> start;

// Find Minimum Cost Spanning Tree (MST) using Prim's algorithm


std::vector<Edge> MST = primMST(graph, start);

// Print Minimum Cost Spanning Tree (MST)


std::cout << "Minimum Cost Spanning Tree (MST):\n";
int totalWeight = 0;
for (const Edge& edge : MST) {
std::cout << edge.to << " - " << edge.weight << std::endl;
totalWeight += edge.weight;
}
std::cout << "Total weight of MST: " << totalWeight << std::endl;

return 0;
}
10. Write programs to

(a) Implement All-Pairs Shortest Paths problem using Floyd's algorithm.

#include <iostream>
#include <vector>
#include <limits>

using namespace std;

const int INF = numeric_limits<int>::max();

vector<vector<int>> floydWarshall(const vector<vector<int>>& graph) {


int n = graph.size();
vector<vector<int>> dist(graph);

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


for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
if (dist[i][k] != INF && dist[k][j] != INF && dist[i][k] + dist[k][j] < dist[i][j]) {
dist[i][j] = dist[i][k] + dist[k][j];
}
}
}
}

return dist;
}

int main() {
// Example usage
vector<vector<int>> graph = {
{0, 5, INF, 10},
{INF, 0, 3, INF},
{INF, INF, 0, 1},
{INF, INF, INF, 0}
};

vector<vector<int>> shortestDistances = floydWarshall(graph);

// Print shortest distances


for (auto& row : shortestDistances) {
for (int distance : row) {
if (distance == INF) {
cout << "INF ";
} else {
cout << distance << " ";
}
}
cout << endl;
}

return 0;
}
(b) Implement Travelling Sales Person problem using Dynamic programming.

#include <iostream>
#include <vector>
#include <cmath>
#include <algorithm>
#include <limits>

const int INF = std::numeric_limits<int>::max();

// Function to calculate the distance between two points (cities)


double distance(const std::pair<int, int>& p1, const std::pair<int, int>& p2) {
return std::sqrt(std::pow(p1.first - p2.first, 2) + std::pow(p1.second - p2.second, 2));
}

// Function to solve the Travelling Salesman Problem using Dynamic Programming


double tspDynamicProgramming(const std::vector<std::pair<int, int>>& cities) {
int n = cities.size();
std::vector<std::vector<double>> dp(1 << n, std::vector<double>(n, INF));

// Base case: If there is only one city


dp[1][0] = 0;

// Dynamic programming loop


for (int mask = 1; mask < (1 << n); ++mask) {
for (int last = 0; last < n; ++last) {
if (mask & (1 << last)) {
for (int cur = 0; cur < n; ++cur) {
if (mask != (1 << cur) && (mask & (1 << cur))) {
dp[mask][cur] = std::min(dp[mask][cur], dp[mask ^ (1 << cur)][last] +
distance(cities[last], cities[cur]));
}
}
}
}
}

// Finding the minimum cost of the cycle


double minCost = INF;
for (int i = 1; i < n; ++i) {
minCost = std::min(minCost, dp[(1 << n) - 1][i] + distance(cities[i], cities[0]));
}

return minCost;
}

int main() {
int n;
std::cout << "Enter the number of cities: ";
std::cin >> n;

std::vector<std::pair<int, int>> cities(n);


std::cout << "Enter the coordinates of each city:\n";
for (int i = 0; i < n; ++i) {
std::cin >> cities[i].first >> cities[i].second;
}

double minCost = tspDynamicProgramming(cities);


std::cout << "Minimum cost of the tour: " << minCost << std::endl;

return 0;
}
11. Design and implement in CPP, to find a subset of a given set S = {Sl, S2,.....,Sn} of n
positive integers whose SUM is equal to a given positive integer d. For example, if S ={1, 2,
5, 6, 8} and d= 9, there are two solutions {1,2,6}and {1,8}. Display a suitable message, if the
given problem instance doesn't have a solution

#include <iostream>
#include <vector>

// Function to find a subset of a given set whose sum is equal to a given positive integer
void findSubset(const std::vector<int>& set, int n, int targetSum) {
std::vector<std::vector<bool>> dp(n + 1, std::vector<bool>(targetSum + 1, false));

// Base case: subset sum with sum 0 is always possible


for (int i = 0; i <= n; ++i)
dp[i][0] = true;

// Fill the dp table


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

// Retrieve the subset


if (dp[n][targetSum]) {
std::cout << "Subset with sum " << targetSum << " found: {";
int i = n, j = targetSum;
while (i > 0 && j > 0) {
if (dp[i][j] == dp[i - 1][j])
--i;
else {
std::cout << set[i - 1];
j -= set[i - 1];
if (j > 0) std::cout << ",";
--i;
}
}
std::cout << "}" << std::endl;
} else {
std::cout << "No subset found with sum " << targetSum << std::endl;
}
}
int main() {
std::vector<int> set = {1, 2, 5, 6, 8};
int targetSum = 9;

findSubset(set, set.size(), targetSum);

return 0;
}
12. Design and implement in CPP to find all Hamiltonian Cycles in a connected undirected
Graph G of n vertices using backtracking principle.

#include <iostream>
#include <vector>
#include <algorithm>

class Graph {
private:
int V; // Number of vertices
std::vector<std::vector<int>> adj; // Adjacency list

// Function to check if vertex v can be added at index 'pos' in the Hamiltonian cycle
bool isSafe(int v, const std::vector<int>& path, int pos) {
// Check if vertex v is adjacent to the previously added vertex in the path
if (!adj[path[pos - 1]][v])
return false;

// Check if vertex v is already included in the path


for (int i = 0; i < pos; ++i)
if (path[i] == v)
return false;

return true;
}

// Function to recursively find Hamiltonian cycle starting from the vertex 'pos'
bool hamiltonianCycleUtil(std::vector<int>& path, int pos) {
// If all vertices are included in the path, and the last vertex is adjacent to the first vertex,
then it's a Hamiltonian cycle
if (pos == V) {
if (adj[path[pos - 1]][path[0]] == 1)
return true;
else
return false;
}

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


if (isSafe(v, path, pos)) {
path[pos] = v;

if (hamiltonianCycleUtil(path, pos + 1))


return true;

path[pos] = -1; // Backtrack


}
}

return false;
}

public:
Graph(int vertices) : V(vertices), adj(vertices, std::vector<int>(vertices, 0)) {}

// Function to add an edge to the graph


void addEdge(int u, int v) {
adj[u][v] = 1;
adj[v][u] = 1;
}

// Function to find all Hamiltonian cycles in the graph


void findHamiltonianCycles() {
std::vector<int> path(V, -1);

// Add the first vertex to the path


path[0] = 0;

if (!hamiltonianCycleUtil(path, 1)) {
std::cout << "No Hamiltonian cycle exists in the graph\n";
return;
}

std::cout << "Hamiltonian cycles in the graph:\n";


do {
for (int v : path)
std::cout << v << " ";
std::cout << path[0] << "\n";
} while (std::next_permutation(path.begin() + 1, path.end())); // Generate all permutations
of the remaining vertices
}
};

int main() {
Graph g(5); // Create a graph with 5 vertices

// Add edges to the graph


g.addEdge(0, 1);
g.addEdge(0, 2);
g.addEdge(0, 3);
g.addEdge(0, 4);
g.addEdge(1, 2);
g.addEdge(1, 3);
g.addEdge(1, 4);
g.addEdge(2, 3);
g.addEdge(2, 4);
g.addEdge(3, 4);

// Find and print all Hamiltonian cycles in the graph


g.findHamiltonianCycles();

return 0;
}

You might also like