I made this implementation for this problem :
http://www.spoj.pl/problems/SHOP/
#include<iostream>
#include<stdio.h>
#include<queue>
#include<conio.h>
#include<string.h>
using namespace std;
struct node
{
int x;
int y;
int time;
};
bool operator <(const node &s,const node &r)
{
if(s.time>r.time)
return true;
else return false;
}
node beg,src,dest,tempa;
int b,a,temp;
int map[25][25];
bool vis[25][25];
int X[]={1,0,-1,0};
int Y[]={0,1,0,-1};
int djs_bfs(node src,node dest)
{
int result=0;
priority_queue<node>pq;
pq.push(src);
while(!pq.empty())
{
node top = pq.top();
pq.pop();
if(top.x==dest.x && top.y==dest.y) return result;
if(top.x<0 || top.x>=a) continue;
if(top.y<0 || top.y>=b) continue;
if(vis[top.x][top.y]) continue;
vis[top.x][top.y]=true;
result+=map[top.x][top.y];
for(int i=0;i<4;i++)
{
tempa.x=top.x+X[0];
tempa.y=top.y+Y[0];
tempa.time=map[top.x+X[0]][top.y+Y[0]];
pq.push(tempa);
}
}
return -1;
}
int main()
{
memset(vis,false,sizeof(vis));
scanf("%d %d",&a,&b);
while(a != 0)
{
for(int i=0;i<a;i++)
for(int j=0;j<b;j++)
{
scanf("%c",&temp);
if(temp=='X') {map[i][j]=0;vis[i][j]=true;}
if(temp=='S') {src.x=i;src.y=j;src.time=0;}
if(temp=='D') {dest.x=i;dest.y=j;dest.time=0;}
else map[i][j]=temp-'0';
}
cout<<djs_bfs(src,dest)<<endl;
scanf("%d %d",&a,&b);
}
return 0;
getch();
}
I don’t know why my code doesn’t generate the right answer for the testcases.
If someone can help me improve the code, please do so 😀
First of all, the graph parsing code is incorrect. The first line specifies width and height, where the width is the number of characters per line the height is the number of lines. Therefore, swap
&aand&bin the first scanf, or swap the order of the nestedforloops (but not both). Also, I had to add dummyscanf("%c", &dummy);calls at various places to filter out newlines. A simple dump, such as this, will help determine if your map was parsed correctly:Note: I also set
map[i][j]to 0 for ‘S’ and ‘D’, also changing the repeatedifstatements into anif; else if; elsechain. This makes the algorithm more robust, since you can generically add time from the source or destination.Now, on to the algorithm itself….
Each loop of the algorithm increments
resultby the current map location weight. However, the algorithm is searching multiple paths simultaneously (i.e., the number of entries in the priority queue), and thereforeresultends up being the sum of all processed node weights, not the current path weight. The current path weight istop.temp, and therefore you can eliminate theresultvariable and simply returntop.tempwhen you reach the destination.Also, as other answers noted, you need to use
X[i]andY[i]in your inner loop, otherwise you are only searching in one direction.Now, because of the addition/subtraction from
X[i]andY[i], you will likely accessmap[][]out of range (-1 or 25). Therefore, I recommend moving theifguards to the innerforloop to guard against the out-of-range access. This also avoids filling the priority queue with illegal possibilities.Here is my version of the algorithm, with minimal corrections, for reference:
I hope this helps.