BZOJ1744: [Usaco2005 oct]Skiing 奶牛滑雪
n<=100 * m<=100的地图,每个数绝对值不超过25,从1,1到n,m,一开始速度v,从数字A走到数字B速度会变成v*2^(A-B),求到终点最短时间。
可以发现,相同的数字出发的速度是一样的,和(1,1)位置的数的差做2的指数再乘v,而一个点只有四条边,跑个最短路即可。
然后n,m打反调了1.5h。。
1 #include<stdio.h> 2 #include<string.h> 3 #include<stdlib.h> 4 #include<algorithm> 5 #include<queue> 6 //#include<iostream> 7 using namespace std; 8 9 int n,R,C,v; 10 #define maxn 10011 11 #define maxm 80011 12 int a[111][111];double pw[111]; 13 struct Graph 14 { 15 struct Edge{int to,next;double v;}edge[maxm];int first[maxn],le; 16 Graph() {memset(first,0,sizeof(first));le=2;} 17 void in(int x,int y,double v) {Edge &e=edge[le];e.to=y;e.v=v;e.next=first[x];first[x]=le++;} 18 double dis[maxn];bool vis[maxn]; 19 struct qnode 20 { 21 int id;double v; 22 bool operator > (const qnode &b) const {return v>b.v;} 23 }; 24 priority_queue<qnode,vector<qnode>,greater<qnode> > q; 25 double dijkstra(int s,int t) 26 { 27 memset(vis,0,sizeof(vis)); 28 for (int i=1;i<=n;i++) dis[i]=1e15;dis[s]=0; 29 q.push((qnode){s,0}); 30 while (!q.empty()) 31 { 32 const int now=q.top().id;const double d=q.top().v;q.pop(); 33 if (vis[now]) continue; 34 vis[now]=1; 35 for (int i=first[now];i;i=edge[i].next) 36 { 37 const Edge &e=edge[i]; 38 if (dis[e.to]>d+e.v) 39 { 40 dis[e.to]=d+e.v; 41 q.push((qnode){e.to,dis[e.to]}); 42 } 43 } 44 } 45 return dis[t]; 46 } 47 }g; 48 int main() 49 { 50 pw[0]=1.0; 51 for (int i=1;i<=50;i++) pw[i]=pw[i-1]*2; 52 for (int i=-1;i>=-50;i--) pw[i]=pw[i+1]/2; 53 scanf("%d%d%d",&v,&R,&C); 54 for (int i=1;i<=R;i++) 55 for (int j=1;j<=C;j++) 56 scanf("%d",&a[i][j]); 57 n=R*C; 58 for (int i=1;i<=R;i++) 59 for (int j=1;j<=C;j++) 60 { 61 double now=1.0/(pw[a[1][1]-a[i][j]]*v); 62 int id=(i-1)*C+j; 63 if (j>1) g.in(id,id-1,now); 64 if (j<C) g.in(id,id+1,now); 65 if (i>1) g.in(id,id-C,now); 66 if (i<R) g.in(id,id+C,now); 67 } 68 printf("%.2f\n",g.dijkstra(1,n)); 69 return 0; 70 }