题目链接:https://www.nowcoder.com/acm/contest/118/A
这道题有两种解法,一是直接用优先队列去写,二是bfs+松弛操作。第一种就是简单的优先队列实现,第二种需要注意起点和终点的负数需要改成0,因为只能操作非负数,而且不需要判断终点的结束条件。
优先队列:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <queue>
using namespace std;
struct Node{
int x,y,step;
bool operator < (const Node &a) const{
return a.step < step;
}
}Next,Now,S,E;
int n;
int MAP[105][105];
int vis[105][105];
int dir[4][2] = {1,0,0,1,-1,0,0,-1};
bool in(int x,int y){
if(x >= 0&& y >= 0 && x < n && y < n && vis[x][y] == 0)return true;
return false;
}
int bfs(){
priority_queue<Node> q;
memset(vis,0,sizeof(vis));
S.step = 0;
q.push(S);
while(!q.empty()){
Now = q.top();
// printf(" %d\n",MAP[Now.x][Now.y]);
q.pop();
if(Now.x == E.x && Now.y == E.y){
return Now.step;
}
for(int i=0;i<4;i++){
Next.x = Now.x + dir[i][0];
Next.y = Now.y + dir[i][1];
if(in(Next.x,Next.y)){
vis[Next.x][Next.y] = 1;
Next.step = Now.step + MAP[Next.x][Next.y];
q.push(Next);
}
}
}
return -1;
}
int main()
{
while(~scanf("%d",&n)){
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
scanf("%d",&MAP[i][j]);
if(MAP[i][j] == -1){
S.x = i;
S.y = j;
}
if(MAP[i][j] == -2){
E.x = i;
E.y = j;
}
}
}
int temp = bfs();
printf("%d\n",temp+2);
}
return 0;
}
BFS+最短路:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <queue>
using namespace std;
int MAP[105][105];
int dir[4][2] = {1,0,0,1,-1,0,0,-1};
int dp[105][105];
int n;
struct Node{
int x,y;
}S,E,Now,Next;
bool in(int x,int y){
if(x >= 0 && y >= 0 && x < n && y < n)return true;
return false;
}
void bfs(){
queue<Node> q;
q.push(S);
while(!q.empty()){
Now = q.front();
q.pop();
// if(Now.x == E.x && Now.y == E.y){ // 因为要把所有的点都跑一遍
// return ;
// }
for(int i=0;i<4;i++){
Next.x = Now.x + dir[i][0];
Next.y = Now.y + dir[i][1];
if(in(Next.x,Next.y)){
if(dp[Next.x][Next.y] > dp[Now.x][Now.y] + MAP[Next.x][Next.y]){ // 松弛
dp[Next.x][Next.y] = dp[Now.x][Now.y] + MAP[Next.x][Next.y];
q.push(Next);
}
}
}
}
return ;
}
int main()
{
while(~scanf("%d",&n)){
memset(dp,0x3f3f3f3f,sizeof(dp));
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
scanf("%d",&MAP[i][j]);
if(MAP[i][j] == -1){
S.x = i;
S.y = j;
dp[i][j] = 0; // 起点为0
MAP[i][j] = 0; // 不能存在负数
}
if(MAP[i][j] == -2){
E.x = i;
E.y = j;
MAP[i][j] = 0;
}
}
}
bfs();
printf("%d\n",dp[E.x][E.y]);
}
return 0;
}