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; }