Sicily 1321. Robot

题目大意:给出一个矩阵,每个格子有不同的消耗,给出起点和终点,求从起点走到终点要求消耗最小的路径。

例如:
Sicily <wbr>1321. <wbr>Robot
思路:其实就是求矩阵的最短路径。也就是dijkstra算法,实现方法有很多,可以用一个矩阵记录每个点到起点的消耗(初始化为无穷大),搜索,若有更小的则更新;再一种是直接用优先队列来求,这保证了每一步都是最优的,时间复杂度和空间复杂度都比上一种方法更优,下面代码便是用这种方法。
PS:关于最短路径算法dijkstra,最关键的理解我认为是从起点开始,直接相连的初始化为各自路径大小,其他的为无穷大,下一步就选最小的那个,同时更新其它的点到起点的路径大小。
 1 #include <iostream>
 2 #include <cstdio>
 3 #include <queue>
 4 #include <memory.h> 
 5 using namespace std;
 6 
 7 struct Node
 8 {
 9     int r,c;
10     int cost;
11     friend bool operator <(Node a,Node b)
12 {
13 return a.cost>b.cost; 
14 } 
15 };
16 int main()
17 {
18     int t;
19     cin>>t;
20     while(t--)
21     {
22         int n,m;
23         cin>>n>>m;
24         int matrix[n+1][m+1];
25         bool v[n+1][m+1];
26 memset(v,false,sizeof(v)); 
27         int f[8]={-1,0,0,1,1,0,0,-1}; 
28         for(int i=1;i<n+1;i++)
29             for(int j=1;j<m+1;j++)
30                 scanf("%d",&matrix[i][j]);
31         int sx,sy,dx,dy;
32         cin>>sx>>sy>>dx>>dy;
33         priority_queue<Node> q;
34         Node s;
35         s.r=sx;
36         s.c=sy;
37         s.cost=matrix[s.r][s.c];
38         Node now=s;
39         int row,col; 
40         while(!(now.r==dx&&now.c==dy)){
41             for(int i=0;i<8;i+=2){
42 row=now.r+f[i];
43 col=now.c+f[i+1]; 
44 if(row>0&&row<n+1&&col>0&&col<m+1&&!v[row][col])
45 {
46 Node next;
47 next.r=row;
48 next.c=col;
49 next.cost=now.cost+matrix[row][col]; 
50 q.push(next); 
51 } 
52 } 
53             now=q.top();          //这里要注意一下,不能直接q.pop()再直接取得头部,这样会超时,因为有一些节点我们已经找到了
54 //最短路径,可是队列里仍存在我们以前push进去的未更新的节点,直接pop的话会重复做很多工作 
55 while(v[now.r][now.c]){
56 q.pop();
57 now=q.top(); 
58 } 
59 v[now.r][now.c]=true; 
60         }
61         cout<<now.cost<<endl; 
62     }
63     return 0; 
64 }

 

posted @ 2012-09-19 09:07  晨风世界  阅读(322)  评论(0编辑  收藏  举报