题意:
有个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; }