hdu3345[BFS和SPFA]

来源:互联网 发布:红杉网络 编辑:程序博客网 时间:2024/05/24 11:14

题目叙述

War chess is hh’s favorite game:
In this game, there is an N * M battle map, and every player has his own Moving Val (MV). In each round, every player can move in four directions as long as he has enough MV. To simplify the problem, you are given your position and asked to output which grids you can arrive.
In the map:
‘Y’ is your current position (there is one and only one Y in the given map).
‘.’ is a normal grid. It costs you 1 MV to enter in this gird.
‘T’ is a tree. It costs you 2 MV to enter in this gird.
‘R’ is a river. It costs you 3 MV to enter in this gird.
‘#’ is an obstacle. You can never enter in this gird.
‘E’s are your enemies. You cannot move across your enemy, because once you enter the grids which are adjacent with ‘E’, you will lose all your MV. Here “adjacent” means two grids share a common edge.
‘P’s are your partners. You can move across your partner, but you cannot stay in the same grid with him final, because there can only be one person in one grid.You can assume the Ps must stand on ‘.’ . so ,it also costs you 1 MV to enter this grid.

算法思路

  1. 很显然的BFS搜索,但是从这一题而言,我们可以看出一些事情。
  2. 只是使用布尔数组来标记走过的路显然是不行的。我们扩展的点是存在优先级的。也就是说,经过结点数目更多的路径反而消耗的能量要少。
  3. 所以,我们记录下到达某个节点的时候剩下能量最多的个数,使用队列来进行BFS搜索,显然,队列当中存在多个相同的结点是没有意义的。所以我们再记录下当前的结点是否在队列当中。
  4. 突然之间,我们发现,这就是我们接触过的spfa算法。

代码

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<vector>#include<queue>using namespace std;#define MAXN 105#define INF 0x3f3f3f3fint movex[4] = {1,-1,0,0};int movey[4] = {0,0,1,-1};struct status{    int curx,cury;    status(){}    status(int a,int b){        curx = a;        cury = b;    }};char grid[MAXN][MAXN];int visited[MAXN][MAXN];bool inQueue[MAXN][MAXN];int r,c,mv,t;int stx,sty;bool adjenermy(int x,int y){//judge if the person is next to the //  enermy    if(x>0&&grid[x-1][y]=='E')return true;    if(y>0&&grid[x][y-1]=='E')return true;    if(x<r-1&&grid[x+1][y]=='E')return true;    if(y<c-1&&grid[x][y+1]=='E')return true;    return false;}int mustcost(char c){//comoute the cost of the step    if(c=='.')return 1;    if(c=='T')return 2;    if(c=='R')return 3;    if(c=='P')return 1;    else return INF;}bool Judge(int x,int y,int mvl){//judge if the step is available    if(x<0||y<0||x>=r||y>=c)return false;    if(mvl - mustcost(grid[x][y])<0)return false;    else if(grid[x][y]=='P'&&mvl==1)return false;    return true;}void print(){//print the final answer    int i,j;    for(i=0;i<r;i++){        for(j=0;j<c;j++){            if(grid[i][j]=='#'||grid[i][j]=='P'||grid[i][j]=='Y'||visited[i][j]<0)                printf("%c",grid[i][j]);            else                printf("*");        }        printf("\n");    }    printf("\n");}void Solve(){//solve the question with SPFA    int i;    memset(visited,-1,sizeof(visited));    memset(inQueue,false,sizeof(inQueue));    visited[stx][sty] = mv;    queue<status>Q;    status st = status(stx,sty);    Q.push(st);    inQueue[stx][sty] = true;    while(!Q.empty()){        status cur = Q.front();        Q.pop();        inQueue[cur.curx][cur.cury] = false;        //judgr if the current position is next to        //thr enermy        if(adjenermy(cur.curx,cur.cury)&&grid[cur.curx][cur.cury]!='Y')continue;        for(i=0;i<4;i++){            if(Judge(cur.curx+movex[i],cur.cury+movey[i],visited[cur.curx][cur.cury])){                char c = grid[cur.curx+movex[i]][cur.cury+movey[i]];                status next = status(cur.curx+movex[i],cur.cury+movey[i]);                int temp = visited[cur.curx][cur.cury]-mustcost(c);                if(temp > visited[next.curx][next.cury]){                    visited[next.curx][next.cury] = temp;                    if(!inQueue[next.curx][next.cury]){                        Q.push(next);                        inQueue[next.curx][next.cury] = true;                    }                }            }        }    }    print();}int main(){    freopen("input","r",stdin);    int i,j;    scanf("%d",&t);    while(t--){        scanf("%d%d%d",&r,&c,&mv);        for(i=0;i<r;i++){            scanf("%s",grid[i]);            for(j=0;j<c;j++){                if(grid[i][j] == 'Y'){                    stx = i;                    sty = j;                }            }        }        Solve();    }    return 0;}
0 0
原创粉丝点击