0% found this document useful (0 votes)
13 views75 pages

Created By: Abhinav Rawat CSE4A1 Roll No-08

The document outlines algorithms and implementations for various graph-related problems including path existence, bipartiteness, cycle detection, and shortest path calculations using Dijkstra's and Bellman-Ford algorithms. Each section provides a clear algorithm followed by C++ code to implement the solution. The document is structured with input and output formats, along with example outputs for clarity.

Uploaded by

git.sumitjoshi
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
13 views75 pages

Created By: Abhinav Rawat CSE4A1 Roll No-08

The document outlines algorithms and implementations for various graph-related problems including path existence, bipartiteness, cycle detection, and shortest path calculations using Dijkstra's and Bellman-Ford algorithms. Each section provides a clear algorithm followed by C++ code to implement the solution. The document is structured with input and output formats, along with example outputs for clarity.

Uploaded by

git.sumitjoshi
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 75

W6Q1- Given a (directed/undirected) graph, design an algorithm and implement it using a program to

find if a path exists between two given vertices or not. (Hint: use DFS).
Input Format: Input will be the graph in the form of adjacency matrix or adjacency list. Source vertex
number and destination vertex number is also provided as an input.
Output Format: Output will be 'Yes Path Exists' if path exists, otherwise print 'No Such Path Exists'.
ALGORITHM :
1. Build the graph using an adjacency list from the given edges.
2. Create a visited array and mark all nodes as unvisited.
3. Start DFS from the source node.
4. Mark the current node as visited.
5. For each neighbor of the current node, if it is not visited, call DFS recursively on that neighbor.
6. After DFS finishes, check if the destination node is visited.
7. If visited, print "Yes Path Exists".
8. Otherwise, print "No Such Path Exists".

#include <iostream>
#include <vector>
using namespace std;
void dfs(int node, vector<vector<int>>& graph, vector<bool>& visited) {
visited[node] = true;
for (int neighbor : graph[node]) {
if (!visited[neighbor]) {
dfs(neighbor, graph, visited);
}
}
}
int main() {
int nodes, edges;
cout << "Enter number of nodes and edges: ";
cin >> nodes >> edges;
vector<vector<int>> graph(nodes);

Created By: Abhinav Rawat CSE4A1 Roll No- 08


cout << "Enter " << edges << " edges (u v):" << endl;
for (int i = 0; i < edges; ++i) {
int u, v;
cin >> u >> v;
graph[u].push_back(v); // For undirected graph, also add graph[v].push_back(u);
}
int source, destination;
cout << "Enter source and destination: ";
cin >> source >> destination;
vector<bool> visited(nodes, false);
dfs(source, graph, visited);
if (visited[destination]) {
cout << "Yes Path Exists" << endl;
} else {
cout << "No Such Path Exists" << endl; }}

OUTPUT:

Created By: Abhinav Rawat CSE4A1 Roll No- 08


W6Q2: Given a graph, design an algorithm and implement it using a program to find if a graph is
bipartite or not. (Hint: use BFS)
Input Format: Input will be the graph in the form of adjacency matrix or adjacency list.
Output Format: Output will be 'Yes Bipartite' if graph is bipartite, otherwise print 'Not Bipartie
ALGORITHM
1. Initialize a color array of size equal to the number of nodes, and set all values to -1 to represent
that no node has been colored yet.
2. For each node in the graph, do the following:
3. If the node is not colored (color[node] == -1), start a BFS from this node to color its connected
component.
4. Create a queue and push the current node into it.
5. Assign color 0 to this node to start coloring.
6. While the queue is not empty, do the following:
7. Remove the front node from the queue, call it current.
8. For each neighbor of the current node, check the color:
9. If the neighbor is not colored, assign it the opposite color of the current node (if current is 0,
assign 1; if current is 1, assign 0), and add this neighbor to the queue.
10. If the neighbor has the same color as the current node, it means two connected nodes share the
same color, so the graph is not bipartite. Immediately return false.
11. If the BFS finishes without conflicts for all connected components of the graph, return true
indicating the graph is bipartite.

#include <iostream>
#include <vector>
#include <queue>
using namespace std;
bool isBipartite(vector<vector<int>>& graph, int nodes) {
vector<int> color(nodes, -1);
for (int start = 0; start < nodes; ++start) {
if (color[start] == -1) {
queue<int> q;
q.push(start);
color[start] = 0;
while (!q.empty()) {

Created By: Abhinav Rawat CSE4A1 Roll No- 08


int current = q.front();
q.pop();
for (int neighbor : graph[current]) {
if (color[neighbor] == -1) {
color[neighbor] = 1 - color[current];
q.push(neighbor);
} else if (color[neighbor] == color[current]) {
return false;
}
}
}
}
}
return true;
}
int main() {
int nodes, edges;
cout << "Enter number of nodes and edges: ";
cin >> nodes >> edges;
vector<vector<int>> graph(nodes);
cout << "Enter " << edges << " edges (u v):" << endl;
for (int i = 0; i < edges; ++i) {
int u, v;
cin >> u >> v;
graph[u].push_back(v);
graph[v].push_back(u);
}

Created By: Abhinav Rawat CSE4A1 Roll No- 08


if (isBipartite(graph, nodes)) {
cout << "Yes Bipartite" << endl;
} else {
cout << "Not Bipartite" << endl;
}
return 0;
}

OUTPUT:

Created By: Abhinav Rawat CSE4A1 Roll No- 08


W6Q3- Given a directed graph, design an algorithm and implement it using a program to find whether
cycle exists in the graph or not.
Input Format: Input will be the graph in the form of adjacency matrix or adjacency list.
Output Format: Output will be 'Yes Cycle Exists' if cycle exists otherwise print 'No Cycle Exists'.
ALGORITHM:
1. Initialize two arrayslists:
2. visited[] to keep track of which nodes have been visited
3. inRecStack[] to keep track of nodes currently in the recursion stack (i.e., the path we are
exploring)
4. For each node in the graph:
5. If the node is not visited, call a DFS function on it
6. Inside the DFS function for a node:
7. Mark the current node as visited
8. Mark the current node as part of the recursion stack (inRecStack[node] = true)
9. For every neighbor of the current node:
10. If the neighbor is not visited, recursively call DFS on the neighbor
11. If the recursive call returns true (cycle found), propagate true upwards
12. Else if the neighbor is already in the recursion stack, it means there is a back edge and hence a
cycle, so return true immediately
13. After exploring all neighbors of the current node, remove the current node from the recursion
stack (inRecStack[node] = false)
14. Return false indicating no cycle found from this node

#include <iostream>
#include <vector>
using namespace std;
bool dfs(int node, vector<vector<int>>& graph, vector<bool>& visited, vector<bool>& inRecStack) {
visited[node] = true;
inRecStack[node] = true;
for (int neighbor : graph[node]) {
if (!visited[neighbor]) {
if (dfs(neighbor, graph, visited, inRecStack))
return true;
} else if (inRecStack[neighbor]) {

Created By: Abhinav Rawat CSE4A1 Roll No- 08


return true; // cycle found
}
}
inRecStack[node] = false;
return false;
}
bool hasCycle(vector<vector<int>>& graph, int nodes) {
vector<bool> visited(nodes, false);
vector<bool> inRecStack(nodes, false);
for (int i = 0; i < nodes; ++i) {
if (!visited[i]) {
if (dfs(i, graph, visited, inRecStack))
return true;
}
}
return false;
}
int main() {
int nodes, edges;
cout << "Enter number of nodes and edges: ";
cin >> nodes >> edges;
vector<vector<int>> graph(nodes);
cout << "Enter " << edges << " directed edges (u v):" << endl;
for (int i = 0; i < edges; ++i) {
int u, v;
cin >> u >> v;
graph[u].push_back(v);

Created By: Abhinav Rawat CSE4A1 Roll No- 08


}
if (hasCycle(graph, nodes)) {
cout << "Yes Cycle Exists" << endl;
} else {
cout << "No Cycle Exists" << endl;
}
return 0;
}

OUTPUT:

Created By: Abhinav Rawat CSE4A1 Roll No- 08


W7Q1- After end term examination, Akshay wants to party with his friends. All his friends are living as
paying guest and it has been decided to first gather at Akshay’s house and then move towards party
location. The problem is that no one knows the exact address of his house in the city. Akshay as a
computer science wizard knows how to apply his theory subjects in his real life and came up with an
amazing idea to help his friends. He draws a graph by looking in to location of his house and his friends’
location (as a node in the graph) on a map. He wishes to find out shortest distance and path covering that
distance from each of his friend’s location to his house and then whatsapp them this path so that they
can reach his house in minimum time. Akshay has developed the program that implements Dijkstra’s
algorithm but not sure about correctness of results. Can you also implement the same algorithm and
verify the correctness of Akshay’s results? (Hint: Print shortest path and distance from friends’ location
to Akshay’s house)
ALGORITHM
1. Initialize:
 A distance array dist[] with size equal to number of nodes, where all values are set to infinity
(or a very large number) except dist[start] = 0
 A parent array parent[] to store the predecessor of each node on the shortest path, initialized
to -1
 A priority queue (min-heap) pq to efficiently get the next node with the smallest tentative
distance
2. Insert the start node into the priority queue with distance 0
3. While the priority queue is not empty:
4. Extract the node current with the smallest distance currentDist from pq
5. For each neighbor next of current with edge weight weight:
6. If the distance to next can be improved by going through current (i.e., if dist[next] > currentDist
+ weight):
7. Update dist[next] = currentDist + weight
8. Update parent[next] = current
9. Insert next into the priority queue with the updated distance

#include <iostream>
#include <vector>
#include <queue>
#include <stack>
#include <climits>
using namespace std;
void dijkstra(int start, vector<vector<pair<int, int>>>& graph, vector<int>& dist, vector<int>& parent)
{
int n = graph.size();

Created By: Abhinav Rawat CSE4A1 Roll No- 08


dist.assign(n, INT_MAX);
parent.assign(n, -1);
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq;
dist[start] = 0;
pq.push({0, start});
while (!pq.empty()) {
int current = pq.top().second;
int currentDist = pq.top().first;
pq.pop();
for (auto neighbor : graph[current]) {
int next = neighbor.first;
int weight = neighbor.second;
if (dist[next] > currentDist + weight) {
dist[next] = currentDist + weight;
parent[next] = current;
pq.push({dist[next], next});
}
}
}
}
void printPath(int node, vector<int>& parent) {
stack<int> path;
while (node != -1) {
path.push(node);
node = parent[node];
}
while (!path.empty()) {

Created By: Abhinav Rawat CSE4A1 Roll No- 08


cout << path.top();
path.pop();
if (!path.empty()) cout << " -> ";
}
cout << endl;
}
int main() {
int nodes, edges;
cout << "Enter number of nodes and edges: ";
cin >> nodes >> edges;
vector<vector<pair<int, int>>> graph(nodes);
cout << "Enter " << edges << " edges (from to weight):" << endl;
for (int i = 0; i < edges; i++) {
int from, to, weight;
cin >> from >> to >> weight;
graph[from].push_back({to, weight});
graph[to].push_back({from, weight});
}
int start;
cout << "Enter starting node: ";
cin >> start;
vector<int> dist, parent;
dijkstra(start, graph, dist, parent);
cout << "\nShortest distance and path from each node to starting node:\n";
for (int i = 0; i < nodes; i++) {
if (i == start) continue;
cout << "From node " << i << " to node " << start << ": ";

Created By: Abhinav Rawat CSE4A1 Roll No- 08


if (dist[i] == INT_MAX) {
cout << "No path exists.\n";
} else {
cout << "Distance = " << dist[i] << ", Path = ";
printPath(i, parent);
}
}
return 0;
}

OUTPUT:

Created By: Abhinav Rawat CSE4A1 Roll No- 08


W7Q2- Design an algorithm and implement it using a program to solve previous question's problem
using Bellman- Ford's shortest path algorithm.
ALGORTIHM-
1) Initialize distance array:
 Create dist[] of size n
 Set dist[start] = 0
 Set all other dist[i] = INF
2) Initialize predecessor array:
 Create prev[] of size n
 Set all prev[i] = -1
3) Relax all edges (repeat n-1 times):
 For each edge u→v with weight w:
 If dist[u] != INF and dist[v] > dist[u] + w:
 Update dist[v] = dist[u] + w
 Set prev[v] = u
4) Check for negative cycles:
 For each edge u→v with weight w:
 If dist[u] != INF and dist[v] > dist[u] + w:
 Return "Negative cycle detected"
5) If no negative cycles found:
 dist[] contains shortest distances
 prev[] contains path information

#include <iostream>
#include <vector>
#include <climits>
#include <stack>
using namespace std;
struct Edge {
int u, v, w;
};
void bellmanFord(int n, int m, vector<Edge>& edges, int start, vector<int>& dist, vector<int>& prev) {
dist.assign(n, INT_MAX);
prev.assign(n, -1);
dist[start] = 0;

Created By: Abhinav Rawat CSE4A1 Roll No- 08


for (int i = 0; i < n - 1; i++) {
for (int j = 0; j < m; j++) {
int u = edges[j].u;
int v = edges[j].v;
int w = edges[j].w;
if (dist[u] != INT_MAX && dist[v] > dist[u] + w) {
dist[v] = dist[u] + w;
prev[v] = u;
}
}
}
for (int j = 0; j < m; j++) {
int u = edges[j].u;
int v = edges[j].v;
int w = edges[j].w;
if (dist[u] != INT_MAX && dist[v] > dist[u] + w) {
cout << "Negative cycle found.\n";
return;
}
}
}
void showPath(int node, vector<int>& prev) {
stack<int> path;
while (node != -1) {
path.push(node);
node = prev[node];
}

Created By: Abhinav Rawat CSE4A1 Roll No- 08


while (!path.empty()) {
cout << path.top();
path.pop();
if (!path.empty()) cout << " -> ";
}
cout << endl;
}
int main() {
int n, m;
cout << "Enter number of nodes and edges: ";
cin >> n >> m;
vector<Edge> edges(m);
cout << "Enter edges (from to weight):\n";
for (int i = 0; i < m; i++) {
cin >> edges[i].u >> edges[i].v >> edges[i].w;
}
int start;
cout << "Enter source node: ";
cin >> start;
vector<int> dist, prev;
bellmanFord(n, m, edges, start, dist, prev);
cout << "\nShortest path and distance from each node to source:\n";
for (int i = 0; i < n; i++) {
if (i == start) continue;
cout << "From node " << i << " to node " << start << ": ";
if (dist[i] == INT_MAX) {
cout << "No path exists.\n";

Created By: Abhinav Rawat CSE4A1 Roll No- 08


} else {
cout << "Distance = " << dist[i] << ", Path = ";
showPath(i, prev);
}
}
return 0;}

OUTPUT:

Created By: Abhinav Rawat CSE4A1 Roll No- 08


W7Q3- Given a directed graph with two vertices ( source and destination). Design an algorithm and
implement it using a program to find the weight of the shortest path from source to destination with
exactly k edges on the path.
ALGORITHM-
1. If k equals 0:
2. If src equals dest: return 0
3. Else: return INF (very large number)
4. If k greater than 0:
5. Set answer = INF
6. For each edge src→neighbor with weight w:
7. Recursively find cost from neighbor to dest with k-1 edges
8. Add w to recursive result
9. Update answer = min(answer, w + recursive_result)
10. Return answer
11. If after all edges checked, answer is still infinity, it means no path with exactly k edges exists from
src to dest.

#include <iostream>
#include <vector>
#include <climits>
using namespace std;
const int INF = INT_MAX;
int shortestPathWithKEdges(vector<vector<pair<int,int>>>& graph, int u, int dest, int k) {
if (k == 0 && u == dest) return 0;
if (k == 0) return INF;
int ans = INF;
for (auto &edge : graph[u]) {
int next = edge.first;
int weight = edge.second;
int sub = shortestPathWithKEdges(graph, next, dest, k - 1);
if (sub != INF) {
ans = min(ans, weight + sub);
}

Created By: Abhinav Rawat CSE4A1 Roll No- 08


}
return ans;
}
int main() {
int n, e;
cout << "Enter number of nodes and edges: ";
cin >> n >> e;
vector<vector<pair<int,int>>> graph(n);
cout << "Enter edges (from to weight):\n";
for (int i=0; i<e; i++) {
int u, v, w;
cin >> u >> v >> w;
graph[u].push_back({v, w});
}
int src, dest, k;
cout << "Enter source, destination and k (number of edges): ";
cin >> src >> dest >> k;
int result = shortestPathWithKEdges(graph, src, dest, k);
if (result == INF) {
cout << "No path exists with exactly " << k << " edges.\n";
} else {
cout << "Shortest path weight with exactly " << k << " edges is: " << result << "\n";
}}

Created By: Abhinav Rawat CSE4A1 Roll No- 08


OUTPUT:

Created By: Abhinav Rawat CSE4A1 Roll No- 08


W8Q1: Assume that a project of road construction to connect some cities is given to your friend. Map of
these cities and roads which will connect them (after construction) is provided to him in the form of a
graph. Certain amount of rupees is associated with construction of each road. Your friend has to
calculate the minimum budget required for this project. The budget should be designed in such a way
that the cost of connecting the cities should be minimum and number of roads required to connect all the
cities should be minimum (if there are N cities then only N-1 roads need to be constructed). He asks you
for help. Now, you have to help your friend by designing an algorithm which will find minimum cost
required to connect these cities. (use Prim's algorithm)

ALGORITHM:
1. Create three arrays:
 visited[] = false for all nodes
 minEdge[] = ∞ (very large) for all nodes, except minEdge[0] = 0
 parent[] = -1 for all nodes
2. Repeat n times (where n is the number of nodes):
a. Find the unvisited node u with the smallest minEdge[u]
b. If no such u exists (i.e., disconnected graph), stop
c. Mark u as visited
d. Add minEdge[u] to total cost
e. For every node v:
If v is not visited and cost[u][v] < minEdge[v], then update minEdge[v] = cost[u][v] and set
parent[v] = u
3. After the loop, total cost is the sum of all selected edges
4. parent[] array stores the MST (Minimum Spanning Tree) edges

#include <iostream>
#include <vector>
#include <climits>
using namespace std;

int prim(int n, vector<vector<int>>& cost) {


vector<bool> visited(n, false);

Created By: Abhinav Rawat CSE4A1 Roll No- 08


vector<int> minEdge(n, INT_MAX);
minEdge[0] = 0;
int totalCost = 0;
for (int i = 0; i < n; i++) {
int u = -1;
for (int j = 0; j < n; j++) {
if (!visited[j] && (u == -1 || minEdge[j] < minEdge[u])) {
u = j;
}
}
visited[u] = true;
totalCost += minEdge[u];
for (int v = 0; v < n; v++) {
if (!visited[v] && cost[u][v] < minEdge[v]) {
minEdge[v] = cost[u][v];
}
}
}
return totalCost;
}
int main() {
int n;
cout << "Enter number of cities: ";
cin >> n;
vector<vector<int>> cost(n, vector<int>(n));
cout << "Enter cost matrix (enter 0 if no direct road):\n";
for (int i = 0; i < n; i++) {

Created By: Abhinav Rawat CSE4A1 Roll No- 08


for (int j = 0; j < n; j++) {
cin >> cost[i][j];
if (cost[i][j] == 0 && i != j) cost[i][j] = INT_MAX;
}
}
int minCost = prim(n, cost);
cout << "Minimum budget required to connect all cities: " << minCost << "\n";
return 0;
}

OUTPUT:

Created By: Abhinav Rawat CSE4A1 Roll No- 08


W8Q2: Implement the previous problem using Kruskal's algorithm.
ALGORITHM:
1. Read the number of vertices V and the number of edges E, then read each edge as a triple (u, v,
w) into a list called edgeList.
2. Create two arrays of length V+1, called parent and rank. For each vertex i from 1 to V, set
parent[i] = i and rank[i] = 0.
3. Sort edgeList in order of increasing weight w.
4. Prepare an empty list MST and set totalCost = 0 and edgesUsed = 0.
5. For each edge (u, v, w) in the sorted list, do the following:
o To determine whether adding this edge would form a cycle, locate the representative
(root) of u by following parent pointers until you reach a vertex that is its own parent;
along the way, reset each visited vertex’s parent directly to the root (“path compression”).
Call this rootU. Do the same for v to get rootV.
o If rootU and rootV are different, include the edge in MST, add w to totalCost, and
increment edgesUsed by 1. Then merge the two sets: compare rank[rootU] and
rank[rootV]; attach the lower-rank tree beneath the higher-rank tree; if the ranks are
equal, choose one root to be parent of the other and increment its rank by 1.
o If edgesUsed reaches V – 1, stop processing further edges.

6. When finished, MST contains exactly V – 1 edges, and totalCost is the weight of the minimum
spanning tree.

#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> pii;
int find(int i, vector<int>& parent) {
if(i == parent[i]) return i;
return parent[i] = find(parent[i], parent);
}
void Union(int a, int b, vector<int> &rank, vector<int>& parent){
int x = find(a, parent);
int y = find(b, parent);

Created By: Abhinav Rawat CSE4A1 Roll No- 08


if(x == y) return;
if(rank[x] == rank[y]) {
parent[x] = y;
rank[y]++;
}
else if(rank[x] < rank[y]){
parent[x] = y;
}
else parent[y] = x;
}
int Kruskal(const vector<pair<int, pii>>& edges, vector<pair<int, pii>>& MST, int V){
int MinCost = 0, count = 0;
vector<int> parent(V + 1);
vector<int> rank(V + 1, 0);
for(int i = 1; i <= V; i++)
parent[i] = i;
for(int i = 0; i < edges.size() && count < V - 1; i++){
int w = edges[i].first;
int u = edges[i].second.first;
int v = edges[i].second.second;
int x = find(u, parent);
int y = find(v, parent);
if(x != y) {
MinCost += w;
Union(x, y, rank, parent);
MST.push_back({w , {u , v}});
count++;

Created By: Abhinav Rawat CSE4A1 Roll No- 08


}
}
return MinCost;
}
int main(){
int v, e;
cout << "Enter the number of vertices: " << endl;
cin >> v;
cout << "Enter the number of edges: " << endl;
cin >> e;
vector<pair<int, pii>> edges;
vector<pair<int, pii>> MST;
int src, dest, wt;
cout << "Enter the edges: (src dest wt)" << endl;
for(int i = 0; i < e; i++){
cin >> src >> dest >> wt;
edges.push_back({wt , {src, dest}});
}
sort(edges.begin(), edges.end());
int minCost = Kruskal(edges, MST, v);
cout << "\nMinimum Cost: " << minCost << endl;
cout << "\nEdges in the Minimum Spanning Tree:\n";
for(auto it: MST){
cout << "Edge: " << it.second.first << " - " << it.second.second << " , Weight: " << it.first << endl;
}
return 0;
}

Created By: Abhinav Rawat CSE4A1 Roll No- 08


OUTPUT:

Created By: Abhinav Rawat CSE4A1 Roll No- 08


W8Q3- Assume that same road construction project is given to another person. The amount he will earn
from this project is directly proportional to the budget of the project. This person is greedy, so he
decided to maximize the budget by constructing those roads who have highest construction cost. Design
an algorithm and implement it using a program to find the maximum budget required for the project.
ALGORITHM-
1. Read the number of vertices V and the number of edges E.
2. Read each edge as a triple (u, v, w) into a list called edgeList.
3. Create two arrays of size V+1:
 parent[i] ← i for i = 1…V
 rank[i] ← 0 for i = 1…V
4. Sort edgeList in descending order of weight w.
5. Initialize totalCost ← 0 and edgesUsed ← 0.
6. For each edge (u, v, w) in the sorted list, do:
a. Find rootU = Find(u) by following parent pointers (with path compression).
b. Find rootV = Find(v) by the same method.
c. If rootU ≠ rootV:
 totalCost ← totalCost + w
 Union(rootU, rootV) by attaching the smaller‐rank tree under the larger (increment rank
if equal)
 edgesUsed ← edgesUsed + 1
 If edgesUsed = V − 1, stop.
7. The value totalCost is the maximum budget (sum of the V–1 largest non‐cycle edges).

#include <bits/stdc++.h>
using namespace std;
typedef pair<int,int> pii;

int findSet(int i, vector<int>& parent) {


if (parent[i] == i) return i;
return parent[i] = findSet(parent[i], parent);
}

Created By: Abhinav Rawat CSE4A1 Roll No- 08


void unionSets(int a, int b, vector<int>& rank, vector<int>& parent) {
int x = findSet(a, parent);
int y = findSet(b, parent);
if (x == y) return;
if (rank[x] < rank[y]) {
parent[x] = y;
} else if (rank[x] > rank[y]) {
parent[y] = x;
} else {
parent[y] = x;
rank[x]++;
}
}

int KruskalMax(const vector<pair<int,pii>>& edges, int V) {


int totalCost = 0, edgesUsed = 0;
vector<int> parent(V+1), rank(V+1, 0);
for (int i = 1; i <= V; i++)
parent[i] = i;
for (auto &e : edges) {
int w = e.first, u = e.second.first, v = e.second.second;
int ru = findSet(u, parent), rv = findSet(v, parent);
if (ru != rv) {
totalCost += w;
unionSets(ru, rv, rank, parent);
edgesUsed++;
if (edgesUsed == V - 1) break;

Created By: Abhinav Rawat CSE4A1 Roll No- 08


}
}
return totalCost;
}

int main() {
int V, E;
cout << "Enter number of vertices: " << endl;
cin >> V;
cout << "Enter number of edges: " << endl;
cin >> E;
vector<pair<int,pii>> edges;
cout << "Enter edges (src dest weight):" << endl;
for (int i = 0; i < E; i++) {
int u, v, w;
cin >> u >> v >> w;
edges.push_back({w, {u, v}});
}
sort(edges.begin(), edges.end(), greater<>());
int maxBudget = KruskalMax(edges, V);
cout << "\nMaximum Budget (Total Cost): " << maxBudget << endl;
return 0;
}

Created By: Abhinav Rawat CSE4A1 Roll No- 08


OUTPUT:

Created By: Abhinav Rawat CSE4A1 Roll No- 08


W9Q1- Given a graph, Design an algorithm and implement it using a program to implement
FloydWarshall all pair shortest path algorithm.
ALGORITHM-
1. Read the number of vertices n.
2. Read the adjacency matrix representing the graph.
3. Replace all zeros (except diagonal elements) with a large number INF to represent no direct
edge.
4. Use three nested loops over all vertices k, i, and j.
5. For each pair of vertices (i, j), check if going through an intermediate vertex k offers a shorter
path than the currently known shortest path.
6. Update dist[i][j] with the minimum of the current value and dist[i][k] + dist[k][j].
7. Repeat this process for every possible intermediate vertex k.
8. After processing all intermediate vertices, the dist matrix will hold the shortest distances between
every pair of vertices.
9. Print the dist matrix. If no path exists between two vertices, print INF.

#include <iostream>
#include <vector>
using namespace std;
const int INF = 1e9;
int main() {
int n;
cout << "Enter number of vertices: ";
cin >> n;
cout << "Enter adjacency matrix (0 for no edge except diagonal):\n";
vector<vector<int>> dist(n, vector<int>(n));
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
cin >> dist[i][j];
if (i != j && dist[i][j] == 0) {
dist[i][j] = INF; // no edge
}

Created By: Abhinav Rawat CSE4A1 Roll No- 08


}
}
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] + dist[k][j] < dist[i][j]) {
dist[i][j] = dist[i][k] + dist[k][j];
}
}
}
}
cout << "All pairs shortest distances:\n";
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (dist[i][j] == INF)
cout << "INF ";
else
cout << dist[i][j] << " ";
}
cout << "\n";
}
return 0;
}

Created By: Abhinav Rawat CSE4A1 Roll No- 08


OUTPUT:

Created By: Abhinav Rawat CSE4A1 Roll No- 08


W9Q2- Given a knapsack of maximum capacity w. N items are provided, each having its own value and
weight. You have to Design an algorithm and implement it using a program to find the list of the
selected items such that the final selected content has weight w and has maximum value. You can take
fractions of items,i.e. the items can be broken into smaller pieces so that you have to carry only a
fraction xi of item i, where 0 ≤xi≤ 1.
ALGORITHM
1. Read the number of items, n, and the knapsack’s capacity, W.
2. For each item i (from 1 to n), read its value vᵢ and weight wᵢ, and compute its value-to-weight
ratio rᵢ = vᵢ / wᵢ.
3. Sort all items in descending order of rᵢ (highest ratio first).
4. Set totalValue = 0 and remainingCapacity = W.
5. For each item in the sorted list, do:
o If its weight wᵢ is less than or equal to remainingCapacity,
• take the entire item,
• add vᵢ to totalValue,
• subtract wᵢ from remainingCapacity,
• record fraction 1.
o Otherwise,
• take fraction f = remainingCapacity / wᵢ,
• add f × vᵢ to totalValue,
• record fraction f,
• set remainingCapacity to 0 and stop.
6. Once the knapsack is full or all items are considered, the recorded fractions specify which
portions to take, and totalValue is the maximum achievable value.

#include<bits/stdc++.h>

using namespace std;

int main(){

int n, w ;

double maxVal = 0.0;

cout << "Enter the number of items: "<<endl;

Created By: Abhinav Rawat CSE4A1 Roll No- 08


cin >> n;

vector<int> wt(n), val(n);

cout << "Enter the weights of n items: "<<endl;

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

cin >> wt[i];

cout << "Enter the values of n items: "<<endl;

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

cin >> val[i];

cout << "Enter the maximum capacity of knackpack: "<<endl;

cin >> w;

vector<pair<double, pair<int, int>>> v(n);

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

double d = (double)val[i] / wt[i];

v[i] = {d, {wt[i], val[i]}};

sort(v.begin() , v.end() , greater<pair<double, pair<int, int>>>());

int i = 0;

while(w != 0 && i < n){

if(v[i].second.first <= w){

maxVal += v[i].second.second;

w -= v[i].second.first;

else {

Created By: Abhinav Rawat CSE4A1 Roll No- 08


maxVal += v[i].first * w;

w = 0;

i++;

cout << "Maximum capacity: " <<maxVal <<endl;

return 0;

OUTPUT:

Created By: Abhinav Rawat CSE4A1 Roll No- 08


W9Q3- Given an array of elements. Assume arr[i] represents the size of file i. Write an algorithm and a
program to merge all these files into single file with minimum computation. For given two files A and B
with sizes m and n, computation cost of merging them is O(m+n). (Hint: use greedy approach)
ALGORITHM
1. Read the number of files, n.
2. Read the size of each file into a list S.
3. Build a min-heap (priority queue) from S so that you can always extract the two smallest sizes in
O(log n) time.
4. Initialize totalCost ← 0.
5. While the heap contains more than one element:
o Extract the two smallest sizes, a and b.

o Compute their merge cost, c ← a + b.

o Add c to totalCost.

o Insert c back into the heap (representing the newly merged file).

6. When only one file remains, you have merged all files with minimum total computation.
7. Output totalCost.

#include<bits/stdc++.h>

using namespace std;

int main(){

int n, minComp = 0;

cout << "Enter the number of files: "<<endl;

cin >> n;

priority_queue<int, vector<int>, greater<int>> files;

cout << "Enter the files: "<<endl;

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

Created By: Abhinav Rawat CSE4A1 Roll No- 08


int x;

cin >> x;

files.push(x);

while(files.size() != 1) {

int x = files.top();

files.pop();

int y = files.top();

files.pop();

minComp += (x + y);

files.push(x + y);

cout << "Minimum computation: " <<minComp <<endl;

return 0;

OUTPUT:

Created By: Abhinav Rawat CSE4A1 Roll No- 08


W10Q1- Given a list of activities with their starting time and finishing time. Your goal is to select
maximum number of activities that can be performed by a single person such that selected activities
must be non-conflicting. Any activity is said to be non-conflicting if starting time of an activity is
greater than or equal to the finishing time of the other activity. Assume that a person can only work on a
single activity at a time.
ALGORTIHM :
1. Read the number of activities, n, and then read each activity’s start and finish times into a list.
2. Sort the list of activities in ascending order of their finish times.
3. Initialize count ← 0 and lastFinish ← –∞.
4. For each activity in the sorted list, in order:
o If the activity’s start time is ≥ lastFinish, select it:
• Increment count by 1.
• Set lastFinish to this activity’s finish time.
5. After processing all activities, count is the maximum number of non‐conflicting activities.

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
struct Activity {
int start, finish;
};
bool cmp(Activity a, Activity b) {
return a.finish < b.finish;
}
int main() {
int n;
cout << "Enter number of activities: ";
cin >> n;
vector<Activity> activities(n);

Created By: Abhinav Rawat CSE4A1 Roll No- 08


cout << "Enter start and finish times of activities:\n";
for (int i = 0; i < n; i++) {
cin >> activities[i].start >> activities[i].finish;
}
sort(activities.begin(), activities.end(), cmp);
cout << "Selected activities (start finish):\n";
int count = 1; // always select first activity
cout << activities[0].start << " " << activities[0].finish << "\n";
int lastFinish = activities[0].finish;
for (int i = 1; i < n; i++) {
if (activities[i].start >= lastFinish) {
cout << activities[i].start << " " << activities[i].finish << "\n";
lastFinish = activities[i].finish;
count++;
}}
cout << "Maximum number of non-conflicting activities: " << count << "\n";
}
OUTPUT:

Created By: Abhinav Rawat CSE4A1 Roll No- 08


W10Q2- Given a long list of tasks. Each task takes specific time to accomplish it and each task has a
deadline associated with it. You have to design an algorithm and implement it using a program to find
maximum number of tasks that can be completed without crossing their deadlines and also find list of
selected tasks.
ALGORITHM
1. Start by taking input for the number of tasks n, and for each task, input the required time and
deadline. Also, assign each task an index to track it later.
2. Sort all the tasks in ascending order of their deadlines. This ensures that tasks with earlier
deadlines are considered first.
3. Initialize a max-heap (priority queue) to keep track of the time of selected tasks and a variable
totalTime to store the cumulative time of selected tasks.
4. Iterate through the sorted list of tasks:
5. Add the current task’s time to totalTime.
6. Push the task’s time and index into the max-heap.
7. If totalTime exceeds the current task’s deadline:
a. Remove the task with the maximum time from the max-heap.
b. Subtract that time from totalTime.
8. This ensures that the most time-consuming task is removed whenever the deadline constraint is
violated.
9. After all tasks are processed, the max-heap contains only those tasks that can be completed
without violating any deadline.
10. Extract the indices of the tasks from the max-heap and optionally sort them if needed.
11. Print the total number of selected tasks and their indices.

#include <iostream>

#include <vector>

#include <queue>

#include <algorithm>

using namespace std;

struct Task {

int time, deadline, index;

};

Created By: Abhinav Rawat CSE4A1 Roll No- 08


bool cmp(Task a, Task b) {

return a.deadline < b.deadline;

int main() {

int n;

cout << "Enter number of tasks: ";

cin >> n;

vector<Task> tasks(n);

cout << "Enter time and deadline for each task:\n";

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

cin >> tasks[i].time >> tasks[i].deadline;

tasks[i].index = i + 1; // to track task number

sort(tasks.begin(), tasks.end(), cmp);

priority_queue<pair<int, int>> maxHeap; // (time, index)

int totalTime = 0;

for (auto& task : tasks) {

totalTime += task.time;

maxHeap.push({task.time, task.index});

if (totalTime > task.deadline) {

totalTime -= maxHeap.top().first; // remove most time-consuming task

maxHeap.pop();

vector<int> selected;

Created By: Abhinav Rawat CSE4A1 Roll No- 08


while (!maxHeap.empty()) {

selected.push_back(maxHeap.top().second);

maxHeap.pop();

sort(selected.begin(), selected.end());

cout << "Maximum number of tasks completed on time: " << selected.size() << "\n";

cout << "Selected task indices: ";

for (int idx : selected) cout << idx << " ";

cout << "\n";

return 0;

OUTPUT:

Created By: Abhinav Rawat CSE4A1 Roll No- 08


W10Q3- Given an unsorted array of elements, design an algorithm and implement it using a program to
find whether majority element exists or not. Also find median of the array. A majority element is an
element that appears more than n/2 times, where n is the size of array
ALGORITHM-
1. Take input for the size of the array n, and then read n elements into an array.
2. To find the majority element, use the Boyer-Moore Voting Algorithm:
a. Initialize candidate as -1 and count as 0.
b. Traverse the array:
i. If count is 0, set candidate to the current element and count to 1.
ii. If the current element is equal to candidate, increment count.
iii. Otherwise, decrement count.
c. After one pass, the candidate may be the majority element.
d. Verify by counting how many times candidate occurs.
e. If it appears more than n/2 times, it's the majority element; otherwise, no majority
element exists.
3. To find the median:
a. Sort the array in non-decreasing order.
b. If the number of elements n is odd, the median is the middle element (i.e., at index n/2).
c. If n is even, the median is the average of the two middle elements: element at n/2 - 1 and
n/2.
4. Print the result:
a. If a majority element is found, print it.
b. Always print the median of the array.

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
// Function to find majority element using Boyer-Moore Voting Algorithm

Created By: Abhinav Rawat CSE4A1 Roll No- 08


int findMajority(vector<int>& arr) {
int candidate = -1, count = 0;
for (int num : arr) {
if (count == 0) {
candidate = num;
count = 1;
} else if (num == candidate) {
count++;
} else {
count--;
}
}
// Verify if candidate is actually majority
count = 0;
for (int num : arr) {
if (num == candidate) count++;
}
if (count > arr.size() / 2) return candidate;
return -1;
}
// Function to find median
double findMedian(vector<int>& arr) {
sort(arr.begin(), arr.end());
int n = arr.size();
if (n % 2 == 1) return arr[n / 2];
return (arr[n / 2 - 1] + arr[n / 2]) / 2.0;
}

Created By: Abhinav Rawat CSE4A1 Roll No- 08


int main() {
int n;
cout << "Enter number of elements: ";
cin >> n;
vector<int> arr(n);
cout << "Enter the elements:\n";
for (int i = 0; i < n; i++) cin >> arr[i];
int majority = findMajority(arr);
double median = findMedian(arr);
if (majority != -1)
cout << "Majority element: " << majority << "\n";
else
cout << "No majority element exists\n";
cout << "Median of the array: " << median << "\n";
return 0;
}

OUTPUT:

Created By: Abhinav Rawat CSE4A1 Roll No- 08


W11Q1- Given a sequence of matrices, write an algorithm to find most efficient way to multiply these
matrices together. To find the optimal solution, you need to find the order in which these matrices
should be multiplied.
ALGORITHM-
1. Start by reading the number of matrices n. Since there are n matrices, there will be n + 1
dimensions provided, stored in an array dims of size n + 1.
2. Initialize a 2D array dp[n][n] to store the minimum number of scalar multiplications needed to
multiply matrices from index i to j. Also initialize another 2D array split[n][n] to store the index
k at which the optimal split occurs.
3. Set all diagonal elements dp[i][i] to 0, because multiplying a single matrix requires no
operations.
4. For each chain length len from 2 to n, perform the following:
o For each starting index i from 0 to n - len, compute the ending index j = i + len - 1.
o Set dp[i][j] to infinity (or a very large number) to begin with.
o For every possible split point k between i and j - 1, compute the cost of multiplying the
chain from i to j by:
 Adding the cost of multiplying matrices from i to k, and k+1 to j
 Adding the cost of multiplying the two resulting matrices, which is dims[i] *
dims[k+1] * dims[j+1]
o If this total cost is less than the current value in dp[i][j], update dp[i][j] with this new
minimum cost and store the split point k in split[i][j].
5. After filling the entire dp table, the minimum number of scalar multiplications to multiply all
matrices is found in dp[0][n-1].
6. To print the optimal order of multiplication, use a recursive function that uses the split[i][j]
array to place parentheses around subproblems, building the multiplication order from bottom
up.
7. End the algorithm.

#include <iostream>
#include <vector>
#include <climits>
using namespace std;
// Function to print the optimal parenthesization
void printOrder(vector<vector<int>>& split, int i, int j) {
if (i == j) {
cout << "M" << i;
return;

Created By: Abhinav Rawat CSE4A1 Roll No- 08


}
cout << "(";
printOrder(split, i, split[i][j]);
cout << " x ";
printOrder(split, split[i][j] + 1, j);
cout << ")";
}
int main() {
int n;
cout << "Enter number of matrices: ";
cin >> n;
vector<int> dims(n + 1);
cout << "Enter dimensions (length " << n + 1 << "):\n";
for (int i = 0; i <= n; i++) cin >> dims[i];
vector<vector<int>> dp(n, vector<int>(n, 0));
vector<vector<int>> split(n, vector<int>(n, 0));
for (int len = 2; len <= n; len++) {
for (int i = 0; i <= n - len; i++) {
int j = i + len - 1;
dp[i][j] = INT_MAX;
for (int k = i; k < j; k++) {
int cost = dp[i][k] + dp[k + 1][j] + dims[i] * dims[k + 1] * dims[j + 1];
if (cost < dp[i][j]) {
dp[i][j] = cost;
split[i][j] = k;
}
}

Created By: Abhinav Rawat CSE4A1 Roll No- 08


}
}
cout << "Minimum number of multiplications: " << dp[0][n - 1] << "\n";
cout << "Optimal multiplication order: ";
printOrder(split, 0, n - 1);
cout << "\n";
return 0;
}

OUTPUT:

Created By: Abhinav Rawat CSE4A1 Roll No- 08


W11Q2- Given a set of available types of coins. Let suppose you have infinite supply of each type of
coin. For a given value N, you have to Design an algorithm and implement it using a program to find
number of ways in which these coins can be added to make sum value equals to N.
ALGORITHM
#include <iostream>
#include <vector>
using namespace std;
int countWays(vector<int>& coins, int n) {
vector<int> dp(n + 1, 0);
dp[0] = 1; // There is 1 way to make sum 0 (use no coins)
for (int coin : coins) {
for (int i = coin; i <= n; i++) {
dp[i] += dp[i - coin];
}
}
return dp[n];
}
int main() {
int numCoins, sum;
cout << "Enter number of coin types: ";
cin >> numCoins;
vector<int> coins(numCoins);
cout << "Enter coin values:\n";
for (int i = 0; i < numCoins; i++) {
cin >> coins[i];
}
cout << "Enter the sum value: ";
cin >> sum;

Created By: Abhinav Rawat CSE4A1 Roll No- 08


int ways = countWays(coins, sum);
cout << "Number of ways to make the sum " << sum << ": " << ways << endl;
return 0;
}

OUTPUT:

Created By: Abhinav Rawat CSE4A1 Roll No- 08


W11Q3- Given a set of elements, you have to partition the set into two subsets such that the sum of
elements in both subsets is same. Design an algorithm and implement it using a program to solve this
problem.
ALGORITHM
1. Take input n, the number of elements in the set.
2. Read n space-separated integers into an array and simultaneously compute their total sum.
3. If the total sum is odd, directly conclude that partitioning into two equal subsets is not possible
and terminate.
4. If the total sum is even, divide the sum by 2. Let this be the target sum we need to find in a
subset.
5. Initialize a 2D boolean table dp of size (n + 1) × (target sum + 1).
6. Set all values in the first column dp[i][0] to true, since a sum of 0 is always possible with any
number of elements by choosing none.
7. Set all values in the first row (except dp[0][0]) to false, since no positive sum is possible with 0
elements.
8. Loop over the array from index 1 to n, and for each element, loop over target sums from 1 to the
target sum:
o If the current element is greater than the target sum j, then set dp[i][j] = dp[i-1][j].
o Otherwise, set dp[i][j] = dp[i-1][j] OR dp[i-1][j - current element].
9. After filling the table, check the value of dp[n][target sum]:
o If it is true, then the set can be partitioned into two subsets with equal sum.
o Otherwise, such a partition is not possible.

#include <bits/stdc++.h>
using namespace std;
bool isSubsetSum(vector<int>& arr, int sum) {
int n = arr.size();
vector<vector<bool>> dp(n + 1, vector<bool>(sum + 1, false));
for(int i = 0 ; i < n + 1; i++){
dp[i][0] = true;
}
for(int i = 1; i < n + 1; i++){
for(int j = 1; j < sum + 1; j++){
if(j < arr[i - 1]) {
dp[i][j] = dp[i - 1][j];

Created By: Abhinav Rawat CSE4A1 Roll No- 08


}
else {
dp[i][j] = dp[i - 1][j] || dp[i - 1][j - arr[i - 1]];
}
}
}
return dp[n][sum];
}

int main() {
int n, sum = 0;
cout << "Enter the size of the array: " << endl;
cin >> n;
vector<int> arr(n);
cout << "Enter the elements of the array: " << endl;
for(int i = 0; i < n; i++){
cin >> arr[i];
sum += arr[i];
}
if(sum % 2 == 0) {
sum /= 2;
if (isSubsetSum(arr, sum)) cout << "Yes, can be partitioned into two subsets with equal sum." <<
endl;
else cout << "No, cannot be partitioned into equal sum subsets." << endl;
}
else cout << "No, cannot be partitioned into equal sum subsets" << endl;
return 0;
}

Created By: Abhinav Rawat CSE4A1 Roll No- 08


OUTPUT:

Created By: Abhinav Rawat CSE4A1 Roll No- 08


W12Q1- Given two sequences, Design an algorithm and implement it using a program to find the length
of longest subsequence present in both of them. A subsequence is a sequence that appears in the same
relative order, but not necessarily contiguous.
ALGORITHM:
1. Take two strings s1 and s2 as input.
2. Let n be the length of s1 and m be the length of s2.
3. Create a 2D table dp of size (n+1) × (m+1) initialized with zeros.
4. Loop over i from 1 to n and for each i, loop over j from 1 to m:
o If the characters s1[i-1] and s2[j-1] are equal, then set dp[i][j] = 1 + dp[i-1][j-1].

o Else, set dp[i][j] = max(dp[i-1][j], dp[i][j-1]).

5. After filling the table, the value at dp[n][m] gives the length of the Longest Common
Subsequence.
6. Print the value of dp[n][m] as the result.

#include <iostream>
#include <vector>
#include <string>
using namespace std;
int longestCommonSubsequence(string s1, string s2) {
int n = s1.size();
int m = s2.size();
vector<vector<int>> dp(n + 1, vector<int>(m + 1, 0));
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
if (s1[i - 1] == s2[j - 1])
dp[i][j] = 1 + dp[i - 1][j - 1];
else
dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);
}
}

Created By: Abhinav Rawat CSE4A1 Roll No- 08


return dp[n][m];
}
int main() {
string s1, s2;
cout << "Enter first sequence: ";
cin >> s1;
cout << "Enter second sequence: ";
cin >> s2;
int length = longestCommonSubsequence(s1, s2);
cout << "Length of Longest Common Subsequence: " << length << endl;
return 0;
}
OUTPUT:

Created By: Abhinav Rawat CSE4A1 Roll No- 08


W12Q2- Given a knapsack of maximum capacity w. N items are provided, each having its own value
and weight. Design an algorithm and implement it using a program to find the list of the selected items
such that the final selected content has weight <= w and has maximum value. Here, you cannot break an
item i.e. either pick the complete item or don't pick it. (0-1 property).
ALGORITHM
1. Read number of items n.
2. Read array of weights for all n items.
3. Read array of values for all n items.
4. Read knapsack capacity W.
5. Create a 2D table memo[n][W+1], initialized with zeros or -1 for memoization.
6. For each item i from 0 to n-1 and for each capacity c from 0 to W:
o If weight of item i is greater than c, set memo[i][c] = memo[i-1][c] (skip item).

o Else, set memo[i][c] = max of:

 memo[i-1][c] (not taking item i)


 value of item i + memo[i-1][c - weight[i]] (taking item i)
7. The maximum achievable value is memo[n-1][W].
8. To find which items are selected, start from memo[n-1][W] and move backward:
o If memo[i][c] != memo[i-1][c], then item i was included; decrease c by weight[i].

o Else, move to i-1 without changing c.

9. Print the maximum value and the list of selected items with their weights and values.

#include <iostream>

#include <vector>

using namespace std;

int knapsack(int idx, int cap, vector<int>& val, vector<int>& wt, vector<vector<int>>& memo) {

if (idx < 0 || cap == 0) return 0;

if (memo[idx][cap] != -1) return memo[idx][cap];

if (wt[idx] > cap)

Created By: Abhinav Rawat CSE4A1 Roll No- 08


return memo[idx][cap] = knapsack(idx - 1, cap, val, wt, memo);

int noTake = knapsack(idx - 1, cap, val, wt, memo);

int take = val[idx] + knapsack(idx - 1, cap - wt[idx], val, wt, memo);

return memo[idx][cap] = max(take, noTake);

void printSelectedItems(int n, int cap, vector<int>& val, vector<int>& wt, vector<vector<int>>&


memo) {

int c = cap;

vector<int> selectedItems;

for (int i = n - 1; i >= 0 && c > 0; i--) {

if (i == 0) {

if (wt[0] <= c && memo[0][c] > 0) {

selectedItems.push_back(0);

} else if (memo[i][c] != memo[i - 1][c]) {

selectedItems.push_back(i);

c -= wt[i];

cout << "Selected items:\n";

cout << "Index\tWeight\tValue\n";

for (int i = (int)selectedItems.size() - 1; i >= 0; i--) {

int idx = selectedItems[i];

cout << idx << "\t" << wt[idx] << "\t" << val[idx] << endl;

Created By: Abhinav Rawat CSE4A1 Roll No- 08


}

int main() {

int n;

cout << "Enter number of items: ";

cin >> n;

vector<int> wt(n), val(n);

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

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

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

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

int capacity;

cout << "Enter knapsack capacity: ";

cin >> capacity;

vector<vector<int>> memo(n, vector<int>(capacity + 1, -1));

int maxVal = knapsack(n - 1, capacity, val, wt, memo);

cout << "\nMaximum value achievable: " << maxVal << endl;

printSelectedItems(n, capacity, val, wt, memo);

return 0;

Created By: Abhinav Rawat CSE4A1 Roll No- 08


OUTPUT:

Created By: Abhinav Rawat CSE4A1 Roll No- 08


W12Q3- Given a string of characters, design an algorithm and implement it using a program to print all
possible permutations of the string in lexicographic order
ALGORITHM-
1. Take input string.
2. Sort the string characters in ascending order to ensure lexicographical order of permutations.
3. Define a recursive function permute with parameters: string s and integer start index.
4. If start equals the length of the string, print the string (a complete permutation) and return.
5. Otherwise, for each index i from start to end of the string:
o Swap characters at positions start and i.

o Recursively call permute with start + 1.

o Swap back the characters to restore original string (backtracking).

6. Call permute with the sorted string and starting index 0 to generate and print all permutations in
lexicographical order.

#include <iostream>
#include <algorithm>
using namespace std;
void permute(string s, int start) {
if (start == (int)s.size()) {
cout << s << "\n";
return;
}
for (int i = start; i < (int)s.size(); i++) {
swap(s[start], s[i]);
permute(s, start + 1);
swap(s[start], s[i]); // backtrack
}
}

Created By: Abhinav Rawat CSE4A1 Roll No- 08


int main() {
string str;
cout << "Enter a string: ";
cin >> str;
sort(str.begin(), str.end()); // Sort to get lex order first
permute(str, 0);
return 0;
}
OUTPUT:

Created By: Abhinav Rawat CSE4A1 Roll No- 08


W13Q1- Given an array of characters, you have to find distinct characters from this array. Design an
algorithm and implement it using a program to solve this problem using hashing. (Time Complexity =
O(n))
ALGORITHM-
1. Read the number of characters n.
2. Read the n characters into an array.
3. Initialize an integer array freq of size 256 (to cover all ASCII characters) with all zeros.
4. Traverse the character array and for each character, increment its corresponding frequency in
freq.
5. Traverse the freq array from 0 to 255 and for each index with a frequency greater than zero, print
the character (cast from the index) and its frequency.

#include <iostream>
using namespace std;
int main() {
int n;
cout << "Enter number of characters: ";
cin >> n;
char arr[n];
cout << "Enter characters:\n";
for (int i = 0; i < n; i++) {
cin >> arr[i];}
int freq[256] = {0};
for (int i = 0; i < n; i++) {
freq[(int)arr[i]]++;
}
cout << "Distinct characters and their frequencies:\n";
for (int i = 0; i < 256; i++) {
if (freq[i] > 0) cout << (char)i << " : " << freq[i] << "\n";
}
return 0;}

Created By: Abhinav Rawat CSE4A1 Roll No- 08


OUTPUT:

Created By: Abhinav Rawat CSE4A1 Roll No- 08


W13Q2- Given an array of integers of size n, design an algorithm and write a program to check whether
this array contains duplicate within a small window of size k < n.

ALGORITHM-
1. Read the number of test cases T.
a. For each test case, do the following:
b. Read the size of the array n.
c. Read the n elements of the array.
d. Read the window size k.
e. Use a data structure (like a hash set) to keep track of elements in the current sliding
window of size k.
f. Traverse the array elements one by one:
i. For each element, check if it already exists in the hash set.
1. If yes, print "Duplicate present in window k" and stop checking for this
test case.
2. If no, add the element to the hash set.
ii. If the current window size exceeds k, remove the element that is left behind (i-k)
from the hash set to maintain the window size.
g. If the entire array is processed without finding duplicates within any window of size k,
print "Duplicate not present in window k".
2. Repeat for all test cases.

#include <iostream>

#include <unordered_set>

#include <vector>

using namespace std;

bool containsDuplicateInWindow(const vector<int>& arr, int k) {

unordered_set<int> window;

for (int i = 0; i < arr.size(); i++) {

Created By: Abhinav Rawat CSE4A1 Roll No- 08


if (window.find(arr[i]) != window.end()) {

return true;

window.insert(arr[i]);

if (window.size() > k) {

window.erase(arr[i - k]);

return false;

int main() {

int T;

cout << "Enter number of test cases: ";

cin >> T;

for (int t = 1; t <= T; t++) {

int n, k;

cout << "\nTest case #" << t << ":\n";

cout << "Enter size of the array: ";

cin >> n;

vector<int> arr(n);

cout << "Enter " << n << " elements:\n";

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

cin >> arr[i];

cout << "Enter window size k: ";

Created By: Abhinav Rawat CSE4A1 Roll No- 08


cin >> k;

if (containsDuplicateInWindow(arr, k)) {

cout << "Duplicate present in window k\n";

} else {

cout << "Duplicate not present in window k\n";

return 0;

OUTPUT:

Created By: Abhinav Rawat CSE4A1 Roll No- 08


W13Q3- Given an array of nonnegative integers, Design an algorithm and implement it using a program
to find two pairs (a,b) and (c,d) such that a*b = c*d, where a, b, c and d are distinct elements of array.
ALGORITHM
1. Read the size of the array n and then read n elements into the array.
2. Initialize an empty map (mp) where the key is an integer product and the value is a list of pairs of
indices (i, j) whose elements multiply to that product.
3. Iterate over all pairs (i, j) in the array where i < j.
4. For each pair, calculate the product p = a[i] * a[j].
5. Check if p already exists as a key in the map.
6. If it exists, iterate over all stored pairs corresponding to product p.
7. For each stored pair (x.first, x.second), verify that none of the indices overlap with the current
pair (i, j) (to ensure all four indices are distinct).
8. If such a pair is found, output the two pairs of elements and terminate the program.
9. If no such pairs are found after checking all pairs, output "No pairs found."

#include <iostream>
#include <unordered_map>
#include <vector>
using namespace std;
int main() {
int n;
cout << "Enter size: ";
cin >> n;
int a[n];
cout << "Enter elements:\n";
for (int i=0; i<n; i++) cin >> a[i];
unordered_map<int, vector<pair<int,int>>> mp;
for (int i=0; i<n; i++) {

Created By: Abhinav Rawat CSE4A1 Roll No- 08


for (int j=i+1; j<n; j++) {
int p = a[i] * a[j];
if (mp.find(p) != mp.end()) {
for (auto &x : mp[p]) {
if (x.first != i && x.first != j && x.second != i && x.second != j) {
cout << "Pairs: (" << a[x.first] << "," << a[x.second] << ") and ("
<< a[i] << "," << a[j] << ")\n";
return 0;}}}
mp[p].push_back({i, j});
}}
cout << "No pairs found.\n";
return 0;}

OUTPUT:

Created By: Abhinav Rawat CSE4A1 Roll No- 08


W14Q1- Given a number n, write an algorithm and a program to find nth ugly number. Ugly numbers
are those numbers whose only prime factors are 2, 3 or 5. The sequence 1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15,
16, 18, 20, 24,..... is sequence of ugly numbers.
ALGORITHM-
1. Initialize an array ugly of size n to store ugly numbers and set ugly[0] = 1 since 1 is considered
the first ugly number.
2. Maintain three indices: i2, i3, and i5, all initialized to 0. These track the position in the ugly
number list for multiples of 2, 3, and 5 respectively.
3. For each position from 1 to n-1:
a. Calculate the next possible multiples:
i. next2 = ugly[i2] * 2
ii. next3 = ugly[i3] * 3
iii. next5 = ugly[i5] * 5
b. Select the minimum among next2, next3, and next5 and assign it to ugly[i].
c. If the selected minimum is equal to next2, increment i2.
d. If the selected minimum is equal to next3, increment i3.
e. If the selected minimum is equal to next5, increment i5.
f. This ensures that duplicates are avoided and the sequence remains sorted.
4. After filling the array up to the nth position, the value at ugly[n-1] is the nth ugly number.
5. Repeat this process for each test case input.

#include <iostream>

#include <vector>

using namespace std;

int nthUglyNumber(int n) {

vector<int> ugly(n);

ugly[0] = 1;

int i2 = 0, i3 = 0, i5 = 0;

Created By: Abhinav Rawat CSE4A1 Roll No- 08


int next2 = 2, next3 = 3, next5 = 5;

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

int nextUgly = min(next2, min(next3, next5));

ugly[i] = nextUgly;

if (nextUgly == next2) {

i2++;

next2 = ugly[i2] * 2;

if (nextUgly == next3) {

i3++;

next3 = ugly[i3] * 3;

if (nextUgly == next5) {

i5++;

next5 = ugly[i5] * 5;

return ugly[n - 1];

int main() {

int T;

cout << "Enter number of test cases: ";

cin >> T;

while (T--) {

Created By: Abhinav Rawat CSE4A1 Roll No- 08


int n;

cout << "Enter n: ";

cin >> n;

int result = nthUglyNumber(n);

cout << "The " << n << "th ugly number is: " << result << "\n";

return 0;

OUTPUT

Created By: Abhinav Rawat CSE4A1 Roll No- 08


W14Q2- Given a directed graph, write an algorithm and a program to find mother vertex in a graph. A
mother vertex is a vertex v such that there exists a path from v to all other vertices of the graph.
ALGORITHM-
1. Initialize a visited array to keep track of visited vertices.
2. Traverse all vertices one by one, and for any vertex not yet visited, perform a Depth First Search
(DFS) from it. Keep track of the last vertex from which DFS finishes. This vertex is a candidate
for mother vertex.
3. After the first pass, reset the visited array.
4. Perform DFS starting from the candidate vertex found in step 2.
5. Check if all vertices are visited in this DFS. If yes, the candidate is a mother vertex.
6. If not all vertices are visited, then there is no mother vertex in the graph.

#include <iostream>
#include <vector>
using namespace std;

void dfs(int v, vector<vector<int>>& g, vector<bool>& visited) {


visited[v] = true;
for (int x : g[v]) {
if (!visited[x]) dfs(x, g, visited);
}
}

int findMother(int n, vector<vector<int>>& g) {


vector<bool> visited(n, false);
int candidate = -1;
for (int i = 0; i < n; i++) {
if (!visited[i]) {
dfs(i, g, visited);
candidate = i;
}

Created By: Abhinav Rawat CSE4A1 Roll No- 08


}
visited.assign(n, false);
dfs(candidate, g, visited);
for (bool v : visited)
if (!v) return -1;
return candidate;
}

int main() {
int n, m;
cout << "Enter vertices and edges: ";
cin >> n >> m;
vector<vector<int>> graph(n);
cout << "Enter edges (from to):\n";
for (int i = 0; i < m; i++) {
int a, b;
cin >> a >> b;
graph[a].push_back(b);
}
int res = findMother(n, graph);
if (res == -1) cout << "No mother vertex\n";
else cout << "Mother vertex: " << res << "\n";
return 0;
}

Created By: Abhinav Rawat CSE4A1 Roll No- 08


OUTPUT:

Created By: Abhinav Rawat CSE4A1 Roll No- 08

You might also like