poj 3037 最短路
大致题意:给出一个矩阵,矩阵内的值的范围为:[-25,25](注意这个范围),从一个格a走到相邻的格b(a,b代表相应格的值)的速度为2^(a-b)*v,时间就是速度的倒数。问从左上角走到右下角所用的最短时间。
很显然是最短路问题,用spfa来求解,该题有一个易出错的地方,因为矩阵内的值范围[-25,25],如果用1<<x的方式求2的幂,很显然这个数会整数超出范围。开始没注意这个问题结果TLE,解决方法可以将1替换为__int64的数。所以dist数组初始化时需将最大值足够大。
#include<iostream>
#include<cstring>
#include<queue>
using namespace std;
#define MAX_INT 11258999068426240000
struct point
{
int x;
int y;
};
queue <point> Q;
int map[101][101],visit[101][101],b[4][2]={-1,0,1,0,0,-1,0,1};
double dist[101][101];
point start;
double spfa(int n,int m,int v)
{
int i,s,x,y;
double k;
__int64 t=1;
dist[1][1]=0;
point e={1,1};
Q.push(e); visit[1][1]=1;
while(!Q.empty())
{
e=Q.front(),Q.pop();
visit[e.x][e.y]=0;
s=map[start.x][start.y]-map[e.x][e.y];
if(s>=0) k=(t<<s)*v;
else k=1.0/(t<<(-s))*v;
for(i=0;i<4;i++)
if(e.x+b[i][0]>0 && e.x+b[i][0]<=n && e.y+b[i][1]>0 && e.y+b[i][1]<=m)
{
x=e.x+b[i][0]; y=e.y+b[i][1];
if(dist[x][y]>dist[e.x][e.y]+1/k)
{
dist[x][y]=1/k+dist[e.x][e.y];
if(!visit[x][y])
{
visit[x][y]=1;
point e1={x,y};
Q.push(e1);
}
}
}
}
return dist[n][m];
}
int main()
{
int i,j,m,n,v;
double k;
while(scanf("%d%d%d",&v,&n,&m)!=EOF)
{
for(i=1;i<=n;i++)
for(j=1;j<=m;j++)
{
scanf("%d",&map[i][j]);
dist[i][j]=MAX_INT;
}
memset(visit,0,sizeof(visit));
start.x=1;start.y=1;
k=spfa(n,m,v);
printf("%.2lf\n",k);
}
return 0;
}
浙公网安备 33010602011771号