poj 3037 最短路

大致题意:给出一个矩阵,矩阵内的值的范围为:[-25,25](注意这个范围),从一个格a走到相邻的格ba,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;
}
posted @ 2011-08-20 17:05  书山有路,学海无涯  阅读(584)  评论(0编辑  收藏  举报