题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=1100
解题思路:广搜+优先队列
自定义优先级用优先队列存最小花费,更新的时候是加s[i][j]-'A'+1。就是这样,没有什么坑点。
AC代码:
#include<bits/stdc++.h>
#define mann 105
using namespace std;
int n,m;
int dx[4]= {0,0,-1,1};
int dy[4]= {-1,1,0,0};
char s[mann][mann];
int vis[mann][mann];
struct node
{
int x,y,temp;
friend bool operator < (node a,node b)//自定义优先级
{
return a.temp>b.temp;//钱小的优先
}
};
priority_queue<node>q;//使用优先队列存最小花费
int bfs(int x1,int y1,int x2,int y2)
{
int xx,yy;
node a= {x1,y1,0};
q.push(a);
vis[x1][y1]=1;
while(!q.empty())
{
a=q.top();
if(a.x==x2&&a.y==y2)
break;
q.pop();
for(int i=0; i<4; i++)
{
xx=a.x+dx[i];
yy=a.y+dy[i];
if(xx>=0&&xx<n&&yy>=0&&yy<m&&!vis[xx][yy]&&s[xx][yy]!='#')
{
node b;
if(s[xx][yy]=='l')//如果当前到达目的地,不同再花费
b= {xx,yy,a.temp};
else//否则,加上当前花费
b= {xx,yy,a.temp+s[xx][yy]-'A'+1};
q.push(b);
vis[xx][yy]=1;
}
}
}
if(q.empty())
return -1;
while(!q.empty())
q.pop();
return a.temp;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
memset(vis,0,sizeof(vis));
int x1,y1,x2,y2;
scanf("%d%d",&n,&m);
for(int i=0; i<n; i++)
scanf("%s",s[i]);
for(int i=0; i<n; i++)
{
for(int j=0; j<m; j++)
{
// printf("%c",s[i][j]);
if(s[i][j]=='s')
x1=i,y1=j;
if(s[i][j]=='l')
x2=i,y2=j;
}
// printf("\n");
}
// printf("%d*%d %d*%d\n",x1,y1,x2,y2);
int ans=bfs(x1,y1,x2,y2);
printf("%d\n",ans);
}
return 0;
}