【BFS+優先佇列】HDU 3442 Three Kingdoms

CN_swords發表於2017-02-25
/* 
Three Kingdoms
時間: 2017/02/25 
題意:劉備逃跑,從'$'逃到'!',除了'.'和'C'能走其他不能走,走'C'處要受傷害,其他字母各有攻擊範圍和傷害值,
問劉備逃跑最少扣的血或不能逃到目的地
題解:全程搜尋 
先BFS搜尋每個有範圍字母能觸及到的位置儲存起來。
再從起點BFS到終點,但是注意要使用優先佇列優化這個BFS。。。
打的比較挫
*/  
#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<queue>
#include<stack>
#include<map>
using namespace std;
#define LL long long
#define N 105
#define INF 0x3f3f3f3f
const double esp = 1e-6;

struct node
{
    int x,y,vis,val;
    bool operator < ( const node& a )const
    {
        return val > a.val;
    }
};
struct point
{
    int x,y,s;
};
int dx[5] = {0,0,1,-1};
int dy[5] = {1,-1,0,0};
char ma[N][N];
bool vis[N][N];
int mp[N][N][10];
int n,m;
bool pan(int x,int y)
{
    if(x >= 0 && x < n && y >= 0 && y < m)
        return true;
    return false;
}
void BFS(int x, int y,int val,int step)
{
    queue<point> p;
    point now,next;
    now.x = x;
    now.y = y;
    now.s = 0;
    p.push(now);
    vis[x][y] = 1;
    while(!p.empty())
    {
        now = p.front();
        p.pop();
        mp[now.x][now.y][val] = 1;
        for(int i = 0; i < 4; i++)
        {
            next.x = dx[i]+now.x;
            next.y = dy[i]+now.y;
            next.s = now.s+1;
            if(pan(next.x,next.y) && vis[next.x][next.y] != 1 && next.s <= step)
            {
                p.push(next);
                vis[next.x][next.y] = 1;
            }
        }
    }
    return ;
}
int ans;
int _BFS(int x, int y)
{
    priority_queue<node> p;
    node now,next;
    now.x = x;
    now.y = y;
    now.vis = 0;
    now.val = 0;
    p.push(now);
    vis[x][y] = 1;
    while(!p.empty())
    {
        now = p.top();
        if(ma[now.x][now.y] == '!')
            return now.val;
        p.pop();
        for(int i = 0; i < 4; i++)
        {
            next.x = dx[i]+now.x;
            next.y = dy[i]+now.y;
            if(pan(next.x,next.y) && vis[next.x][next.y] != 1 && ma[next.x][next.y] != '#')
            {
                next.val = now.val;
                next.vis = now.vis;
                for(int j = 1; j <= 5; j++)
                {
                    if(mp[next.x][next.y][j] && !(now.vis & (1 << (j-1))))
                    {
                        next.val += j;
                        next.vis += (1<<(j-1));
                    }
                }
                p.push(next);
                vis[next.x][next.y] = 1;
            }
        }
    }
    return -1;
}
int main()
{
    int T,cas = 1;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d",&n,&m);
        memset(ma,0,sizeof(ma));
        memset(mp,0,sizeof(mp));
        for(int i = 0; i < n; i++)
            scanf("%s",ma[i]);
        int bx,by;
        for(int i = 0; i < n; i++)
        {
            for(int j = 0; j < m; j++)
            {
                if(ma[i][j] == 'A')
                {
                    ma[i][j] = '#';
                    memset(vis,0,sizeof(vis));
                    BFS(i,j,1,2);
                }
                else if(ma[i][j] == 'B')
                {
                    ma[i][j] = '#';
                    memset(vis,0,sizeof(vis));
                    BFS(i,j,2,3);
                }
                else if(ma[i][j] == 'C')
                {
                    ma[i][j] = '.';
                    mp[i][j][3] = 1;
                }
                else if(ma[i][j] == 'D')
                {
                    ma[i][j] = '#';
                    memset(vis,0,sizeof(vis));
                    BFS(i,j,4,2);
                }
                else if(ma[i][j] == 'E')
                {
                    ma[i][j] = '#';
                    memset(vis,0,sizeof(vis));
                    BFS(i,j,5,1);
                }
                else if(ma[i][j] == '$')
                {
                    bx = i;
                    by = j;
                }
            }
        }
        memset(vis,0,sizeof(vis));
        ans = _BFS(bx,by);
        printf("Case %d: %d\n",cas++,ans);
    }
    return 0;
}

相關文章