题意:
给一个R行C列的地图,g[i][j]表示该点的高度,相邻两点距离为1,初速度为起始点的v速度,末速度为初速*2^下降高度,求(1,1)到(R,C)的最短时间。
分析:
关键是搞清楚在每个点的速度只跟在点(1,1)的初速有关,跟怎么到这个点是没有关系的,因为他们之间的高度差恒定,之后就可以用spfa水了。
代码:
#include <iostream>
#include <queue>
using namespace std;
const double MAX=9999999999999.9;
int V,R,C;
int E[128][128];
double dis[128][128];
double mytime[128][128];
int vis[128][128];
int dx[6]={0,1,-1,0};
int dy[6]={1,0,0,-1};
double getTime(int x,int y)
{
int dH=E[x][y]-E[1][1];
double ans=1;
if(dH>0)
while(dH--)
ans*=2.0;
else{
dH=-dH;
while(dH--)
ans*=0.5;
}
return ans/V;
}
struct Node
{
int x,y;
};
queue<Node> Q;
int main()
{
scanf("%d%d%d",&V,&R,&C);
int i,j,k;
for(i=1;i<=R;++i)
for(j=1;j<=C;++j)
scanf("%d",&E[i][j]);
for(i=1;i<=R;++i)
for(j=1;j<=C;++j)
mytime[i][j]=getTime(i,j);
for(i=1;i<=R;++i)
for(j=1;j<=C;++j)
dis[i][j]=MAX;
memset(vis,0,sizeof(vis));
Node a;
a.x=1,a.y=1;
Q.push(a);
dis[1][1]=0;
vis[1][1]=1;
while(!Q.empty()){
Node u=Q.front();Q.pop();
int x=u.x,y=u.y;
vis[x][y]=0;
for(int j=0;j<4;++j){
int newx=x+dx[j];
int newy=y+dy[j];
if(newx>=1&&newx<=R&&newy>=1&&newy<=C){
double newt=dis[x][y]+mytime[x][y];
if(newt<dis[newx][newy]){
dis[newx][newy]=newt;
if(vis[newx][newy]==0){
vis[newx][newy]=1;
Node b;
b.x=newx,b.y=newy;
Q.push(b);
}
}
}
}
}
printf("%.2lf",dis[R][C]+1e-9);
return 0;
}