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
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.
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.
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.
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.
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?