HDU 1242 (BFS搜索+优先队列)

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

题目大意:多个起点到一个终点,普通点耗时1,特殊点耗时2,求到达终点的最少耗时。

解题思路

如果没有特殊点,就是普通BFS。

由于特殊点的介入,所以对于一个点,可能由不同种方式到达,所以使用优先队列,对于一个点,最先取出的点用的方式肯定是最优的。

同时使用优先队列也为BFS过程提供一个剪枝,因为最先到达肯定是最优结果,只要搜到第一个结果,后面就不用搜了。

注意有多个起点,所以先记录下所有起点,依次BFS找最小。

#include "cstdio"
#include "string"
#include "cstring"
#include "iostream"
#include "vector"
#include "queue"
using namespace std;
#define inf 1<<28
struct status
{
    int x,y,dep;
    status(int x,int y,int dep):x(x),y(y),dep(dep) {}
    bool operator < (const status &a) const
    {
        return dep>a.dep;
    }
};
int n,m,map[205][205],vis[205][205],dir[4][2]={-1,0,1,0,0,-1,0,1},ans;
void bfs(int x,int y)
{
    priority_queue<status> Q;
    Q.push(status(x,y,0));
    bool flag=false;
    while(!Q.empty())
    {
        if(flag) break;
        status t=Q.top();Q.pop();
        vis[t.x][t.y]=true;
        for(int s=0;s<4;s++)
        {
            int X=t.x+dir[s][0],Y=t.y+dir[s][1];
            if(vis[X][Y]||X<0||X>n||Y<0||Y>n||!map[X][Y]) continue;
            if(map[X][Y]==2) {flag=true;ans=min(ans,t.dep+1);};
            if(map[X][Y]==3) Q.push(status(X,Y,t.dep+2));
            else Q.push(status(X,Y,t.dep+1));
        }
    }
}
int main()
{
    //freopen("in.txt","r",stdin);
    ios::sync_with_stdio(false);
    string tt;
    while(cin>>n>>m&&n)
    {
        vector<status> f;
        ans=inf;
        for(int i=1;i<=n;i++)
        {
            cin>>tt;
            for(int j=0;j<tt.size();j++)
            {
                if(tt[j]==‘#‘) map[i][j+1]=0;
                if(tt[j]==‘.‘) map[i][j+1]=1;
                if(tt[j]==‘a‘) map[i][j+1]=2;
                if(tt[j]==‘x‘) map[i][j+1]=3;
                if(tt[j]==‘r‘) {map[i][j+1]=4;f.push_back(status(i,j+1,0));}
            }
        }
        for(int i=0;i<f.size();i++)
        {
            memset(vis,0,sizeof(vis));
            bfs(f[i].x,f[i].y);
        }
        if(ans!=inf) cout<<ans<<endl;
        else cout<<"Poor ANGEL has to stay in the prison all his life."<<endl;
    }
}
11867790 2014-10-14 00:53:01 Accepted 1242 46MS 644K 1840 B C++ Physcal
时间: 2024-10-14 15:58:18

HDU 1242 (BFS搜索+优先队列)的相关文章

HDU 1026 (BFS搜索+优先队列+记录方案)

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1026 题目大意:最短时间内出迷宫.迷宫里要杀怪,每个怪有一定HP,也就是说要耗一定时.输出方案. 解题思路: 要是没有输出方案,就是一个简单粗暴的BFS. 一开始解决输出方案问题时,简单粗暴地在每次状态里加个vector,然后连带vector一起转移. 结果vector的push_back实在太慢,无论怎么优化都是T. 于是参考了ACMan同学的方案,path[X][Y]记录下父亲点. 最后输出的

HDU 1242——Rescue(优先队列)

题意: 一个天使a被关在迷宫里,她的许多小伙伴r打算去救她,求小伙伴就到她需要的最小时间.在迷宫里有守卫,打败守卫需要一个单位时间,如果碰到守卫必须要杀死他 思路: 天使只有一个,她的小伙伴有很多,所以可以让天使找她的小伙伴,一旦找到小伙伴就renturn.时间小的优先级高.优先队列搞定 #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<

HDU 2653 (记忆化BFS搜索+优先队列)

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2653 题目大意:迷宫中有普通点和陷阱.其中普通点可以走可以飞,但是陷阱只能飞.走耗时1,飞耗时2.但是飞耗能1.给定一定能量P,问是否能在T秒内走出. 解题思路: 一开始SB似地认为每个点最多访问两次.其实每个点最多可以访问P次. vis[X][Y][P]表示在(x,y)点能量为P的状态. 容易出错的地方在于这个组合: @. ,虽说是飞吧,但是还是会在陷阱上卡1s,尽管下一个点是. ,但是这种情况

hdu 1242 rescue (优先队列 bfs)

题意: 公主被关在 a位置 她的朋友在r位置 路上x位置有恶魔 遇上恶魔花费2 时间 否在时间花费 1 时间 问 最短多少时间 找到公主 思路: bfs+ 优先队列(时间短的先出列) #include<cstdio> #include<cstring> #include<cmath> #include<queue> #include<iostream> #include<algorithm> using namespace std;

HDU 1180 (BFS搜索)

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1180 题目大意:迷宫中有一堆楼梯,楼梯横竖变化.这些楼梯在奇数时间会变成相反状态,通过楼梯会顺便到达前进方向的下一个点(跳过楼梯). 同时可以在原地等待,问到达终点的最少时间. 解题思路: 很有趣的一个题. 还是先BFS,对于一个楼梯,change函数负责计算出走楼梯能够到达的新的X和Y,再判一次是否越界或不可达. 注意,在'.'点是可以原地等待的,需要额外Push这个点,这也是这题不会出现走不出

HDU 2531 (BFS搜索)

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2531 题目大意: 你的身体占据多个点.每次移动全部的点,不能撞到障碍点,问撞到目标点块(多个点)的最少步数. 解题思路: 挺有趣的一个题,每次要移动多个点. 如果只移动一个点,就是个简单粗暴的BFS. 多个点照样处理,读图的时候把扫到的第一个点当作移动点,然后vector记录下身体的其它点与该移动点的相对坐标. BFS的时候,先看看移动点能不能动,然后再根据身体的相对坐标还原出身体的绝对坐标,看看

HDU 1242 rescue and 优先队列入门

Problem Description Angel was caught by the MOLIGPY! He was put in prison by Moligpy. The prison is described as a N * M (N, M <= 200) matrix. There are WALLs, ROADs, and GUARDs in the prison. Angel's friends want to save Angel. Their task is: approa

HDU 1312 (BFS搜索模板题)

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1312 题目大意:问迷宫中有多少个点被访问. 解题思路: DFS肯定能水过去的.这里就拍了一下BFS. 然后发现自己BFS访问标记有问题,导致某些点被重复访问了. 赶紧改了一下. #include "cstdio" #include "queue" #include "string" #include "cstring" #inc

HDU 2612 (BFS搜索+多终点)

题目链接: http://poj.org/problem?id=1947 题目大意:两人选择图中一个kfc约会.问两人到达时间之和的最小值. 解题思路: 对于一个KFC,两人的BFS目标必须一致. 于是就有以下的SB行为:记录所有KFC,对于每个KFC,对两人BFS.然后你就会看见红红的TLE. 实际上,只需要两次BFS就可以了,用time_k[0][i]记录a同学到达第i个kfc的时间,time_k[1][i]记录b同学到达第i个kfc的时间. 在一次bfs过程中,记录到达所有kfc的时间.