hdu2612(dijkstra)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2612

 

题意:给出一个n*m的矩阵,' . ' 表示可以走的路, ' # '表示不能走的路 ,’ @'表示KCF, ‘Y' , 'M' 表示两个人开始的位置,

他们可以走到相邻的路,每走一步需要11分钟,问他们要在KCF见面,最少需要花多少时间。

 

思路:我们可以把矩阵化成图,再通过dijkstra求出Y和M到各个KCF的距离,然后找对应和最小的就是答案啦。

注意这里矩阵最大为200*200,所以有40000个节点,我们需要对dijkstra做堆优化,不然能会超时。

 

代码:

 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <queue>
 4 #include <string.h>
 5 #define MAXN 210
 6 using namespace std;
 7 
 8 vector<pair<int, int> > vec[MAXN*MAXN];//***记录图
 9 bool vis[MAXN*MAXN];//***标记该点是否在堆中
10 const int inf=0x3f3f3f3f;
11 char mp[MAXN][MAXN];
12 int n, m, pos=0, s1=0, s2=0, a[MAXN*MAXN];
13 
14 struct node{//***重载比较符使优先队列非升序排列
15     int point, value;
16     friend bool operator< (node a, node b){
17         return  a.value>b.value;
18     }
19 };
20 
21 void get_vec(){//建图
22     for(int i=0; i<MAXN*MAXN; i++){
23         vec[i].clear();
24     }
25     for(int i=0; i<n; i++){
26         for(int j=0; j<m; j++){
27             if(mp[i][j]=='@'){
28                 a[pos++]=i*m+j;
29             }else if(mp[i][j]=='Y'){
30                 s1=i*m+j;
31             }else if(mp[i][j]=='M'){
32                 s2=i*m+j;
33             }
34             if(mp[i][j]!='#'){
35                 int u=i*m+j;
36                 if(mp[i+1][j]!='#'&&i+1<n){
37                     int v=(i+1)*m+j;
38                     vec[u].push_back({v, 1});
39                     vec[v].push_back({u, 1});
40                 }
41                 if(mp[i][j+1]!='#'&&j+1<m){
42                     int v=i*m+j+1;
43                     vec[u].push_back({v, 1});
44                     vec[v].push_back({u, 1});
45                 }
46             }
47         }
48     }
49 }
50 
51 int &dijkstra_heap(int s, int dist[MAXN*MAXN]){//最短路求源点到其他点的距离
52     priority_queue<node> q;
53     memset(vis, false, sizeof(vis));
54     dist[s]=0;
55     q.push({s, dist[s]});
56     while(!q.empty()){
57         node u=q.top();
58         int point=u.point;
59         q.pop();
60         if(vis[point]){
61             continue;
62         }else{
63             vis[point]=true;
64         }
65         for(int i=0; i<vec[point].size(); i++){
66             int v=vec[point][i].first;
67             int cost=vec[point][i].second;
68             if(!vis[v]&&dist[v]>dist[point]+cost){//***松驰操作
69                 dist[v]=dist[point]+cost;
70                 q.push({v, dist[v]});
71             }
72         }
73     }
74 }
75 
76 int main(void){
77     while(scanf("%d%d", &n, &m)!=EOF){
78         int dist1[MAXN*MAXN], dist2[MAXN*MAXN];//***记录源点此时到 i 的最短距离
79         memset(dist1, 0x3f, sizeof(dist1));
80         memset(dist2, 0x3f, sizeof(dist2));
81         for(int i=0; i<n; i++){
82             scanf("%s", mp[i]);
83         }
84         pos=0;
85         get_vec();
86         dijkstra_heap(s1, dist1);
87         dijkstra_heap(s2, dist2);
88         int ans=inf;
89         for(int i=0; i<pos; i++){
90             ans=min(dist1[a[i]]+dist2[a[i]], ans);
91         }
92         cout << ans*11 << endl;
93     }
94     return 0;
95 }
View Code

 

posted @ 2017-03-25 20:42  geloutingyu  阅读(107)  评论(0编辑  收藏  举报