首页 > 代码库 > 【POJ3037】Skiing 最短路

【POJ3037】Skiing 最短路

题意:

      有个n*m的滑雪场,bessie要从(1,1)滑到(n,m),问最小时间。

起始有一个速度v,然后每从一个点A到一个点B(只能上下左右走,每次一格),速度就会乘上2^(权值A-权值B)。

然后每次移动的耗时是当前速度的倒数。

题解:

      分析一下就能发现,乘乘除除后,从一个点出发时的速度都是固定的,即与从起点直接到该点的速度是一致的,那么我们就可以建成一个边权固定的无向图了,当然,A->B和B->A的距离基本不可能相等。


这道题很坑,首先就是数据范围很大,需要#define inf 999999999999.99

然后就是错了的话注意C++和G++都交交,然后各种输出.2f和.2lf啊神马的。

然后TLE了不妨多写个几行代码加个pq优化。


      就这些,其实我还TLE这呢,实在是拍不出来错误,受不了了,交了个网上代码,但是我仍然要把我的代码贴一份,以助各位理解,毕竟代码风格不错。

#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define N  105
#define NN 10100
#define M 80000
#define inf 999999999999.99
#define eps 1e-6
using namespace std;
const int dx[4]={0,0,1,-1};
const int dy[4]={1,-1,0,0};
struct KSD
{
	int v,next;
	double len;
}e[M];
int head[NN],cnt;
void add(int u,int v,double len)
{
	cnt++;
	e[cnt].v=v;
	e[cnt].len=len;
	e[cnt].next=head[u];
	head[u]=cnt;
}
int id[N][N],num;
int n,m;
int map[N][N];
double speed[N][N],p;
int power(int x,int p)
{
	int ret=1;
	while(p)
	{
		if(p&1)ret*=x;
		x*=x;
		p>>=1;
	}
	return ret;
}
double dist[NN];
bool in[NN];
struct Lux
{
	double f;
	int v;
	Lux(double _f,int _v):f(_f),v(_v){}
	Lux(){}
	bool operator < (const Lux &a)const
	{return f<a.f;}
};
double spfa(int s,int t)
{
	int i,u,v;
	priority_queue<Lux>q;
	for(i=s;i<=t;i++)dist[i]=inf;
	dist[s]=0;
	in[s]=1;
	q.push(Lux(0,s));
	while(!q.empty())
	{
		Lux U=q.top();
		q.pop();
		u=U.v;
		in[u]=0;
		for(i=head[u];i;i=e[i].next)
		{
			v=e[i].v;
			if(dist[v]>dist[u]+e[i].len+eps)
			{
				dist[v]=dist[u]+e[i].len;
				if(!in[v])
				{
					in[v]=1;
					q.push(Lux(dist[v],v));
				}
			}
		}
	}
	return dist[t];
}
int main()
{
//	freopen("test.in","r",stdin);
	int i,j,k;
	int a,b,c;
	int x,y,nid;
	scanf("%lf%d%d",&p,&n,&m);p=1.0/p;
	for(i=1;i<=n;i++)for(j=1;j<=m;j++)
	{
		id[i][j]=++num;
		scanf("%d",&map[i][j]);
		if(map[i][j]>=map[1][1])speed[i][j]=p*power(2,map[i][j]-map[1][1]);
		else speed[i][j]=p/(double)power(2,map[1][1]-map[i][j]);
	}
	for(i=1;i<=n;i++)for(j=1;j<=m;j++)
	{
		nid=id[i][j];
		for(k=0;k<4;k++)
		{
			x=i+dx[k];
			y=j+dy[k];
			if(!id[x][y])continue;
			add(nid,id[x][y],speed[i][j]);
		}
	}
	printf("%.2f\n",spfa(1,n*m));
	return 0;
}


复制去Google翻译翻译结果

【POJ3037】Skiing 最短路