[01BFS]hdu 2757 Ocean Currents

思路分析

这显然是一个01BFS,根据其性质我们只需要将消耗为0的点放在前面,消耗为1的放在后面再一个一个遍历即可。然后不断更新当前点消耗能量的最小值,待遍历结束后输出ans[tx][ty]即可。这里用queue是不行的,需要使用优先队列来实现上述功能。

注意:不能用vis来标记某个点是否被访问过,因为有可能第一遍被访问的时候并不是最优的解

#include <cstdio>
#include <vector>
#include <cstring>
#include <iostream>
#define xx tmp.x
#define yy tmp.y
#define pp tmp.power
#include <queue>
using namespace std;
char map[1002][1002];
int ans[1002][1002];
int step[8][2]=
{
    -1,0,
    -1,1,
    0,1,
    1,1,
    1,0,
    1,-1,
    0,-1,
    -1,-1
};
int n,m;
int sx,sy,tx,ty;
int que;
struct point
{
    int x,y,power;
    bool operator < (const point &a) const 
    { 
        return power>a.power;//最小值优先 
    } 
};
priority_queue<point> q;
bool inmap(int x,int y){return x>0 && y>0 && x<=n && y<=m;}
void bfs()
{
    register int i,j;
    int nx,ny,nt;
    
    memset(ans,0x7f,sizeof(ans));
    q = priority_queue<point>();
    
    ans[sx][sy] = 0;//显然
    q.push((point){sx,sy,0});
    while(!q.empty())
    {
        point tmp = q.top();
        q.pop();
        for(i=0;i<8;i++)       
        {
            nx = xx + step[i][0];
            ny = yy + step[i][1];
            nt = pp + (i != map[xx-1][yy-1]-'0');//巧妙的写法
            if(nt < ans[tx][ty] && nt < ans[nx][ny] && inmap(nx,ny))//你目前消耗的能量都超过当前最优解了还算个鸡
            {
                if(nx != tx || ny != ty)
                    q.push((point) {nx,ny,nt});
                ans[nx][ny] = nt;
            }
        }
    }
    printf("%d\n",ans[tx][ty]);
}
int main()
{
    register int i,j;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        for(i=0;i<n;i++)cin>>map[i];
        scanf("%d",&que);
        for(i=1;i<=que;i++)
        {
            scanf("%d%d%d%d",&sx,&sy,&tx,&ty);
            if(sx==tx && sy==ty){printf("0\n");continue;}
            bfs();
        }
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值