题意需要注意的是,只能走上下左右。 这题就是寻找map[1][1]到map[r][c]的最短路。 用优先队列的dij解决之。
注意下dis[1][1] = 0; 在dij中必须写上,因为可能有1个点的图。因为这个错了n次。
#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
#include<cmath>
using namespace std;
const int Maxn = 110;
const double inf = 999999999999;
int att[Maxn][Maxn];
int v, r, c;
int di[][2] = {0, 1, 1, 0, 0, - 1, -1, 0};
double map[Maxn][Maxn];
double cost[Maxn][Maxn];
double dis[Maxn][Maxn];
bool vis[Maxn][Maxn];
struct node{
int x,y;
double dis;
bool operator < (const node &a) const{
return dis > a.dis;
}
};
double get_cost(int h)
{
return v*1.0*pow(2*1.0,att[1][1] - h);
}
bool inmap(int x,int y)
{
if(x>0&&x<=r&&y>0&&y<=c)
return true;
else
return false;
}
void ini(){
for(int i = 1; i <= r; ++i)
for(int j = 1; j <= c; ++j)
dis[i][j] = inf;
memset(vis, 0, sizeof(vis));
}
void dij() {
priority_queue<node> q;
node now, next;
now.x = 1, now.dis = 0, now.y = 1;
dis[1][1] = 0;
q.push(now);
while(!q.empty())
{
now = q.top();
q.pop();
if(vis[now.x][now.y])
continue;
vis[now.x][now.y] = true;
if(now.x == r&&now.y == c)
break;
int x, y;
for(int i = 0; i < 4; ++i)
{
x = now.x + di[i][0];
y = now.y + di[i][1];
if(!inmap(x,y))
continue;
if(!vis[x][y]&&dis[x][y] > now.dis+1.0/map[now.x][now.y])
{
dis[x][y] = 1.0 / map[now.x][now.y] + now.dis;
next.x = x; next.dis = dis[x][y];
next.y = y;
q.push(next);
}
}
}
}
int main(void)
{
scanf("%d%d%d",&v,&r,&c);
ini();
for(int i = 1; i <= r; ++i)
{
for(int j = 1; j <= c; ++j)
{
scanf("%d",&att[i][j]);
}
}
for(int i = 1; i <= r; ++i)
for(int j = 1; j <= c; ++j)
{
map[i][j] = get_cost(att[i][j]);
}
dij();
printf("%.2lf\n",dis[r][c]);
return 0;
}
本文介绍了一个基于优先队列实现的Dijkstra最短路径算法,并通过具体代码示例展示了如何寻找从起点到终点的最短路径。该算法适用于地图场景中,仅允许上下左右移动的情况。
388

被折叠的 条评论
为什么被折叠?



