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 }
我就是我,颜色不一样的烟火 --- geloutingyu