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;

}

你可能感兴趣的:(poj)