首页 > 代码库 > Skiing(最短路)

Skiing(最短路)

                            poj——3037 Skiing
Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 4921 Accepted: 1315 Special Judge

Description

Bessie and the rest of Farmer John‘s cows are taking a trip this winter to go skiing. One day Bessie finds herself at the top left corner of an R (1 <= R <= 100) by C (1 <= C <= 100) grid of elevations E (-25 <= E <= 25). In order to join FJ and the other cows at a discow party, she must get down to the bottom right corner as quickly as she can by travelling only north, south, east, and west. 

Bessie starts out travelling at a initial speed V (1 <= V <= 1,000,000). She has discovered a remarkable relationship between her speed and her elevation change. When Bessie moves from a location of height A to an adjacent location of eight B, her speed is multiplied by the number 2^(A-B). The time it takes Bessie to travel from a location to an adjacent location is the reciprocal of her speed when she is at the first location. 

Find the both smallest amount of time it will take Bessie to join her cow friends. 

Input

* Line 1: Three space-separated integers: V, R, and C, which respectively represent Bessie‘s initial velocity and the number of rows and columns in the grid. 

* Lines 2..R+1: C integers representing the elevation E of the corresponding location on the grid.

Output

A single number value, printed to two exactly decimal places: the minimum amount of time that Bessie can take to reach the bottom right corner of the grid.

Sample Input

1 3 31 5 36 3 52 4 3

Sample Output

29.00

Hint

Bessie‘s best route is: 
Start at 1,1 time 0 speed 1 
East to 1,2 time 1 speed 1/16 
South to 2,2 time 17 speed 1/4 
South to 3,2 time 21 speed 1/8 
East to 3,3 time 29 speed 1/4
中文翻译:

滑雪
时间限制:1000MS内存限制:65536k
总提交:4921接受:1315特别法官
描述
Bessie和其他农场主约翰的母牛今年冬天要去滑雪。有一天,贝西发现自己在左上角的R(1 25 = R = = 100)由C(1 = C = C =)网格海拔E(-电子= 25)。为了加入FJ在discow党的其他牛,她必须到右下角,很快她可以通过旅行只有北,南,东,西。
Bessie以初始速度V开始旅行(1 < V = V = 1000000)。她发现她的速度和海拔变化之间有着显著的关系。当Bessie从一个高度位置八B相邻的位置,她的速度乘以2号^(A-B)。Bessie从一个地点到另一个地点旅行的时间是她在第一个位置时速度的倒数。
找到两个最小的时间将采取贝茜加入她的牛朋友。
输入
*第1行:三个空间分离的整数:V,R和C,分别代表Bessie的初始速度和网格中的行和列的数目。
*行2 + R + 1:C整数表示网格上的相应位置的海拔E。
输出
一个单数值,打印到两个完全小数的位置:Bessie可以到达网格右下角的最小时间。
样本输入
1 3 3
1 5 3
6 3 5
2 4 3
示例输出
二十九
提示
Bessie的最佳路线是:
开始时1时0速度1
东到1,2时间1速度1 / 16
南至2时间17速度1 / 4
南至3,2时间21速度1 / 8
东3时间29速度1 / 4

usaco 2005十月黄金

思路:
技术分享

 

题意:你在一个R*C网格的左上角,现在问你从左上角走到右下角需要的最少时间.其中网格中的任意两点的时间花费可以计算出来.
思路:

首先我们需要证明的是从左上角出发到R*C网格中其他任意一点的速度都是固定的.对于下面的矩阵:

1 5 3

6 3 5

2 4 3

我们想计算到数值为6的点时的速度? 从1->6的话 v6=v1*2^(1-6)

而从1->5 5->3 3->6 的话 v6=v1*2^(1-5) * 2^(5-3) * 2^(3-6)=v1*2^(1-6)

相等,同理我们可以证明到任意点的速度为:

 v(i,j)= v1*2^(1号点与该点的海拔之差)

       既然任意点的速度都是固定的,那么从该点到它的4个方向的边的时间开销也是固定的.

       直接建立该无向图,计算出对应每条边的时间开销,然后用最短路算法计算从0号节点到R*C-1点的最短距离(时间开销)即可.

       过程中注意将该网格转换为一个节点编号的无向图的方法.

代码:
 
#include<cstdio>  #include<cstring>  #include<vector>  #include<queue>  #include<cmath>  using namespace std;  const int maxn=10000+10;  #define INF 10000000000  //错误1, 这里INF 之前设为1e8 让我WA,应为最大距离为double 很可能远大于1e8  int R,C;  double v[100+5][100+5];  int height[100+5][100+5];  int dr[]={-1,1,0,0};//上下左右  int dc[]={0,0,-1,1};    struct Edge  {      int from,to;      double dist;      Edge(int from,int to,double dist):from(from),to(to),dist(dist){}  };    struct HeapNode  {      double d;      int u;      HeapNode(double d,int u):d(d),u(u){}      bool operator < (const HeapNode &rhs) const      {          return d > rhs.d;      }  };    struct Dijkstra  {      int n,m;      vector<Edge> edges;      vector<int> G[maxn];      bool done[maxn];      double d[maxn];      int p[maxn];        void init(int n)      {          this->n=n;          for(int i=0;i<n;i++) G[i].clear();          edges.clear();      }        void AddEdge(int from,int to,double dist)      {          edges.push_back(Edge(from,to,dist));          m=edges.size();          G[from].push_back(m-1);      }        void dijkstra()      {          priority_queue<HeapNode> Q;          for(int i=0;i<n;i++) d[i]=INF;          d[0]=0.0;          memset(done,0,sizeof(done));          Q.push(HeapNode(d[0],0));            while(!Q.empty())          {              HeapNode x= Q.top(); Q.pop();              int u=x.u;              if(done[u]) continue;              done[u]=true;                for(int i=0;i<G[u].size();i++)              {                  Edge& e= edges[G[u][i]];                  if(d[e.to] > d[u] + e.dist)                  {                      d[e.to] = d[u]+e.dist;                      p[e.to] = G[u][i];                      Q.push(HeapNode(d[e.to],e.to));                  }              }          }      }  }DJ;    int main()  {      scanf("%lf%d%d",&v[0][0],&R,&C);      for(int i=0;i<R;i++)for(int j=0;j<C;j++)      {          scanf("%d",&height[i][j]);          if(i!=0 || j!=0)          {              v[i][j] = v[0][0]*pow(2.0,height[0][0]-height[i][j]);//速度          }      }        DJ.init(R*C);        for(int r=0;r<R;r++)for(int c=0;c<C;c++)      {          for(int d=0;d<4;d++)          {              int nr = r+dr[d], nc=c+dc[d];              if(nr>=0&&nr<R&&nc>=0&&nc<C)              {                  DJ.AddEdge(r*C+c,nr*C+nc,1.0/v[r][c] );//错误2,之前写成了 r*R+c,nr*R+nc              }          }      }        DJ.dijkstra();        printf("%.2lf\n",DJ.d[R*C-1]);        return 0;  }  

 

 

#include<cstdio>#include<cstdlib>#include<cstring>#include<iostream>#include<algorithm>#define N 101#define maxn 9999999using namespace std;int n,m,v,a[N][N];double ans,dis[N][N];int read(){    int x=0,f=1;    char ch=getchar();    while(ch>9||ch<0)    {        if(ch==-) f=-1;        ch=getchar();    }    while(ch>=0&&ch<=9)    {        x=x*10+ch-0;        ch=getchar();    }    return x*f;}void begin(int n,int m){    for(int i=1;i<=n;i++)     for(int j=1;j<=m;j++)      dis[i][j]=maxn*(i!=j);}int main(){    v=read(),n=read(),m=read();    for(int i=1;i<=n;i++)     for(int j=1;j<=m;j++)        scanf("%d",&a[i][j]);    ans=    printf("%.2lf",ans);    return 0;}

 

 

Skiing(最短路)