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 }
View Code

 

posted @ 2017-09-19 13:41  Blue233333  阅读(254)  评论(0编辑  收藏  举报