#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#include<cmath>
#define N 110
#define INF 1000000
using namespace std;
int n,m,map[N][N];
double d[N][N],V;
bool v[N][N];
int dx[4]={-1,1,0,0},dy[4]={0,0,-1,1};
struct Node
{
int x,y;
};
double spfa()
{
queue<Node>Q;
Node cur,next;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
d[i][j]=INF;
cur.x=1;
cur.y=1;
d[1][1]=0;
v[1][1]=true;
Q.push(cur);
while(!Q.empty())
{
cur=Q.front();
Q.pop();
v[cur.x][cur.y]=false;
double t=1.0/(V*pow(2.0,map[1][1]-map[cur.x][cur.y]));
for(int i=0;i<=3;i++)
{
next.x=cur.x+dx[i];
next.y=cur.y+dy[i];
if(next.x<=n&&next.x>=1&&next.y<=m&&next.y>=1)
{
if(d[next.x][next.y]>d[cur.x][cur.y]+t)
{
d[next.x][next.y]=d[cur.x][cur.y]+t;
if(!v[next.x][next.y])
{
v[next.x][next.y]=true;
Q.push(next);
}
}
}
}
}
return d[n][m];
}
int main()
{
scanf("%lf%d%d",&V,&n,&m);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
scanf("%d",&map[i][j]);
printf("%.2f\n",spfa());
//while(1);
return 0;
}
题目大意:
在一个N*M的矩阵中(N,M<=100) map[i][j]表示该点的高度,在滑雪这个过程中,可以上下左右方向行走,从i到j的速度等于v[i]×2^(A-B),求从左上角(1,1)到右下角(n,m)的最小时间。
题目分析:
两点之间的最小时间,也就是到该点的最大速度,两点的权值就等于速度的倒数,这样一转化,就变成了一个NM的矩阵中,已知map求最短路;
代码如下: