C++ Modify Djikstra's Algorithm To Give Second Shortest Path - c++

How can you modify this Djikstra's algorithm to give the second shortest path? Another way I have done this function is using **G to pass a dynamically initialized 2D array.
I understand the shortest path here, however the second shortest path is confusing.
int main() {
int G[max][max]={{0,1,0,3,10},{1,0,5,0,0},{0,5,0,2,1},{3,0,2,0,6},{10,0,1,6,0}};
int n=5;
int u=0;
dijkstra(G,n,u);
return 0;
}
void dijkstra(int G[max][max],int n,int startnode) {
int cost[max][max],distance[max],pred[max];
int visited[max],count,mindistance,nextnode,i,j;
for(i=0;i<n;i++)
for(j=0;j<n;j++)
if(G[i][j]==0)
cost[i][j]=INFINITY;
else
cost[i][j]=G[i][j];
for(i=0;i<n;i++) {
distance[i]=cost[startnode][i];
pred[i]=startnode;
visited[i]=0;
}
distance[startnode]=0;
visited[startnode]=1;
count=1;
while(count<n-1) {
mindistance=INFINITY;
for(i=0;i<n;i++)
if(distance[i]<mindistance&&!visited[i]) {
mindistance=distance[i];
nextnode=i;
}
visited[nextnode]=1;
for(i=0;i<n;i++)
if(!visited[i])
if(mindistance+cost[nextnode][i]<distance[i]) {
distance[i]=mindistance+cost[nextnode][i];
pred[i]=nextnode;
}
count++;
}
for(i=0;i<n;i++)
if(i!=startnode) {
cout<<"\nDistance of node"<<i<<"="<<distance[i];
cout<<"\nPath="<<i;
j=i;
do {
j=pred[j];
cout<<"<-"<<j;
}while(j!=startnode);
}
}
This algorithm is from tutorials point.

Related

Adjacency List in graph

Hi I am try to implement a graph using adjacency list using following code.
#include<iostream>
#include<list>
#include<vector>
#include<unordered_map>
using namespace std;
class graph{
public:
vector<int> adj[10000];
void insert(int u,int v, bool direction) {
adj[u].push_back(v);
if(direction==1) {
adj[v].push_back(u);
}
}
void print(int n) {
for(int i=0;i<n+1;i++) {
cout<<i<<"->";
for(auto j : adj[i]) {
cout<<j<<",";
}
cout<<endl;
}
}
};
int main( ) {
int n;
cout<<"Enter no of node"<<endl;
cin>>n;
cout<<"enter edges "<<endl;
int m;
cin>>m;
graph g;
for(int i=0;i<m;i++) {
int u, v;
cin>>u>>v;
g.insert(u,v,1);
}
g.print(n);
return 0;
}
But the problem with this code is that it will give correct answer only in the case when my node start from 0 in a continuous manner(0,1,2,3). But when I try to print adjacency list of this graph:
Then it is giving this output:
Can somebody tell me where am I wrong?
The edges you are adding aren't the same as the graph i picture, you are inputting edge 1, 3 instead of edge 1, 5.
It's printing the 0 because you started that for loop from i = 0 and it doesn't print node 5 for the same reason (the loop ends at 4 because you will have i < 4 + 1.
void print(int n) {
//↓↓↓ HERE
for(int i=0;i<n+1;i++) {
cout<<i<<"->";
for(auto j : adj[i]) {
cout<<j<<",";
}
cout<<endl;
}
}
Here is how I would change your code:
First, I changed the print() function a little (added the if() to see if the current row is empty and I changed the int n parameter to int maximum which will hold the highest value node so we know when to stop the for).
void print(int maximum)
{
for(int i=0; i<=maximum; i++)
{
if(!adj[i].empty())
{
cout<<i<<"->";
for(auto j : adj[i])
{
cout<<j<<",";
}
cout<<endl;
}
}
}
Then, in main() I added the maximum and aux variables in order to store the aforementioned highest value node. And I also changed the g.print(n) to g.print(maximum).
int main( )
{
int n, maximum = 0, aux;
cout<<"Enter no of node"<<endl;
cin>>n;
cout<<"enter edges "<<endl;
int m;
cin>>m;
graph g;
for(int i=0; i<m; i++)
{
int u, v;
cin>>u>>v;
g.insert(u,v,1);
aux = max(u, v);
maximum = max(maximum, aux);
}
g.print(maximum);
return 0;
}
However, I might not be Terry A. Davis, but I know that if you say you have 4 nodes, those 4 nodes will be 1 2 3 and 4. And I also know that any graph related problem will have nodes starting from 1, therefore every for loop would start from i = 1, or at least that's how I was taught. The way you did it might be correct too, but I am not sure.

What is the error in this bubble sort code?

I wrote this simple code for bubble sort but it gives some random garbage values as output. Can someone please tell me my mistake. I tried to print the output of A[i] and A[j] in the function bubbleSort and looks like it is working fine. But why is the printSortedArray not giving the correct output? Thanks!
#include <iostream>
using namespace std;
void swap(int *a, int *b)
{
int temp;
temp=*a;
*a=*b;
*b=temp;
}
void printSortedArray(int A[],int size)
{
cout<<"the sorted array is"<<endl;
int i;
for(i=0;i<size;i++);
{
cout<<A[i]<<" ";
}
}
void bubbleSort(int A[],int size)
{
int i,j;
for(i=0;i<size;i++)
{
for(j=0;j<size-1-i;j++)
{
if(A[j]>A[j+1])
{
swap(A[j],A[j+1]);
}
}
}
}
int main()
{
int A[50]; int size,i;
cout<<"enter the size of the array: ";
cin>>size;
cout<<"Enter the "<<size<<" numbers to be sorted"<<endl;
for(i=0;i<size;i++)
{
cin>>A[i];
}
bubbleSort(A,size);
printSortedArray(A,size);
return 0;
}
for(i=0;i<size;i++);
The trailing semicolon does not belong there. This results in undefined behavior.
The end result is that this function printed one garbage value after the end of the array.

Problem with the implementation of DFS recursively

I have tried to implement DFS on my own recursively, but i have a problem. I can't find where my mistake is. I tried to implement it entirely on my own and I am having a problem. Most implementations of DFS I have seen use OOP and I am trying to implement it simply by list of neighbours with dynamic array.
using namespace std;
void DFS(vector<int> *numNodes, int startingVertex, bool* used) {
for(int i:numNodes[startingVertex]) {
if(!used[i]) {
used[i] = true;
cout<<i<<endl;
DFS(numNodes, i, used);
}
}
}
int main()
{
int n, k, temp, startingVertex;
cin>>n;
vector<int> numNodes[n];
for(int i=0; i<n; i++) {
cout<<"How many neighbours for node "<<i<<"?"<<endl;
cin>>k;
cout<<"Enter neighbours"<<endl;
for(int j=0; j<k; j++) {
cin>>temp;
numNodes[i].push_back(temp);
}
}
cout<<"Enter starting point"<<endl;
bool used[n];
for(int i=0; i<n; i++) {
used[i] = false;
}
cin>>startingVertex;
cout<<"Starting DFS from vertex "<<startingVertex<<"..."<<endl;
cout<<startingVertex<<endl;
used[startingVertex] = true;
DFS(numNodes, startingVertex, used);
}
There's a lot of comments on the ticket about good C++/coding practices, but from an algorithmic standpoint, the issue I'm seeing is that after the recursive call of DFS(numNodes, i, used); you need to set used[i] back to false, so that node i can be used again for another path through the graph.

Quick sort implementation in c++

I have pasted my implementation of the quicksort algorithm below. After some debugging I figured out that the recursion of the function quicksort() does not seem to terminate. But it seems to me that my algorithm is fine and I am not able to fix the bug.
/*
quicksort
*/
int a[20];
int partition(int left,int right, int*a)
{
//chose some pivot element- in this case i choose the middle one
int pivot=(left+right)/2;
int b[10],c[10],i=left,j=0;
int k=0;
int pivot_element=a[pivot];
//b is the left side ,c is the right side
while(i<=right)
{
if(a[i]!=pivot_element)
{
if(a[i]<a[pivot])
{
b[j++]=a[i];
}
else
{
c[k++]=a[i];
}
}
i++;
}
//combine
i=left;
for(int q=0;q<j;q++)
a[i++]=b[q];
a[i++]=pivot_element;
for(int p=0;p<k;p++)
a[i++]=c[p];
return j; //return the new position of the pivot
}
void quicksort(int left,int right,int *a)
{
int index=partition(left,right,a);
if(index-left>0)
quicksort(left,index,a);
if(right-index+1>0)
quicksort(index+1,right,a);
}
int main()
{
int size;
cin>>size;
for(int i=0;i<size;i++)
cin>>a[i];
quicksort(0,size-1,a);
for(int i=0;i<size;i++)
cout<<a[i]<<" ";
return 0;
}**
In your partition function, this:
return j;
should be this:
return left+j;
You could have detected this bug by testing the function, before writing other code that called it.
Your recursion lacks a stop criteria.

Segmentation fault in c++ program for dijkstra's algorithm

This is my code.. I tried hard to detect the fault but it compiles properly and then gives segmentation fault while executing...
#include<iostream>
#include<string>
using namespace std;
#define infinity 999
#define MAX 10
int min(int dis[],bool vis[],int n);
void print_dij(int dis[],int n);
class graph
{
int g[MAX][MAX];
public:
int n;
graph()
{
n=0;
}
void readgraph();
void printgraph();
void dij();
};
void graph::readgraph()
{
int i,j;
cout<<"\nEnter the no of vertices::";
cin>>n;
cout<<"\nEnter the adjacency matrix::";
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
cout<<"\n["<<i<<"]["<<j<<"]::";
cin>>g[i][j];
}
}
}
void graph::printgraph()
{
int i,j;
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
cout<<g[i][j];
cout<<"\n";
}
}
void graph::dij()
{
int dis[20],i,j,start,u;
bool vis[20];
cout<<"\nEnter the index number of starting node::";
cin>>start;
for(i=0;i<n;i++)
for(j=0;j<n;j++)
if(g[i][j]==0)
g[i][j]=infinity;
for(i=0;i<n;i++) //Initialising the arrays dis[] and vis[]
{
dis[i]=infinity;
vis[i]=false;
}
dis[start]=0;
for(i=0;i<n-1;i++) //Finding the shortest path
{
u=min(dis,vis,n);
vis[u]=true;
for(j=0;j<n;j++)
if(!vis[j] && g[u][j] && dis[u]!=infinity && dis[u]+g[u][j]<dis[j])
dis[i]=dis[u]+g[u][j];
}
cout<<"\nThe shortest path is::->>>>>\n";
print_dij(dis,n);
}
int min(int dis[],bool vis[],int n) //To find the vertex with min distance from the source
{
int index,i,min=infinity;
for(i=0;i<n;i++)
if(vis[i]=false && dis[i]<=min)
{
min=dis[i];
index=i;
}
return index;
}
void print_dij(int dis[],int n) //To print the shortest path
{
int i;
cout<<"\nVertices\tMinimum distance";
for(i=0;i<n;i++)
{
cout<<"\n"<<i<<"\t"<<dis[i];
}
}
int main()
{
graph g;
int start;
g.readgraph();
cout<<"\nThe entered graph is::\n";
g.printgraph();
g.dij();
return 0;
}
It seems like the fault is in the loop for finding the shortest path in the dij() function. But still i am not able to figure out the problem. Please help me out... :-|
Seems like you have many problem of initialization but with this change your said error would go.
In function int min(int dis[],bool vis[],int n) initialize index to zero.
int index=0
Just a quick question: in min(...) the n is which n? n is graph::n or n from the parameter list?