zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    贝叶斯公式的直观理解(先验概率/后验概率)
    linux生成.so库如何指定添加其他的.so库
    第一章笔记
    高学成
    第一张笔记
    简单编译器之语法分析
    浅析Netty的异步事件驱动(二)
    浅析Netty的异步事件驱动(一)
    简单编译器之词法分析
    Android TV 焦点控制逻辑
  • 原文地址:https://www.cnblogs.com/geloutingyu/p/6618382.html
Copyright © 2011-2022 走看看