您的位置:首页 > 其它

HDU 1242 dfs+剪枝或BFS+优先队列 求最短路

2016-07-15 20:46 309 查看
Rescue

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)

Total Submission(s): 25553 Accepted Submission(s): 9048

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: approach Angel. We assume that “approach Angel” is to get to the position where Angel stays. When there’s a guard in the grid, we must kill him (or her?) to move into the grid. We assume that we moving up, down, right, left takes us 1 unit time, and killing a guard takes 1 unit time, too. And we are strong enough to kill all the guards.

You have to calculate the minimal time to approach Angel. (We can move only UP, DOWN, LEFT and RIGHT, to the neighbor grid within bound, of course.)

Input

First line contains two integers stand for N and M.

Then N lines follows, every line has M characters. “.” stands for road, “a” stands for Angel, and “r” stands for each of Angel’s friend.

Process to the end of the file.

Output

For each test case, your program should output a single integer, standing for the minimal time needed. If such a number does no exist, you should output a line containing “Poor ANGEL has to stay in the prison all his life.”

Sample Input

7 8

.#####.

.a#..r.

..#x…

..#..#.#

…##..

.#……

……..

Sample Output

13

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define INF 0x3f3f3f3f
const int MAXN=205;
int mi;
int N,M,ax,ay;
char mp[MAXN][MAXN];
bool vis[MAXN][MAXN];
void dfs(int x,int y,int d){
if(x<0||x>=N||y<0||y>=M)return ;//越界
if(mp[x][y]=='#')return ;//撞墙
if(mp[x][y]=='x')d++;//特殊情况,遇到守卫d++,
if(vis[x][y]==1)return ;//已访问
if(mp[x][y]=='r'){//终点
if(mi>d){
mi=d;
}
return ;
}
if(d>=mi)return ;//剪枝
vis[x][y]=1;//往下搜
dfs(x,y+1,d+1);
dfs(x+1,y,d+1);
dfs(x-1,y,d+1);
dfs(x,y-1,d+1);
vis[x][y]=0;//搜完记得vis为0
}

int main()
{
while(~scanf("%d%d",&N,&M)){
for(int i=0;i<N;i++)
scanf("%s",mp[i]);
for(int i=0;i<N;i++){
for(int j=0;j<M;j++){
if(mp[i][j]=='a'){
ax=i;
ay=j;
break;
}
}
}
mi=INF;//用来判断能不能到
memset(vis,0,sizeof(vis));//别忘了初始化
dfs(ax,ay,0);
if(mi==INF)printf("Poor ANGEL has to stay in the prison all his life.\n");
else printf("%d\n",mi);
}

return 0;
}


BFS+优先队列:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
#define INF 0x3f3f3f3f
const int MAXN=205;
int N,M,ax,ay;
char mp[MAXN][MAXN];
bool vis[MAXN][MAXN];
int dx[4]={0,0,-1,1};
int dy[4]={-1,1,0,0};

struct node{
int x,y,d;
friend bool operator<(node t1,node t2){
return t1.d>t2.d;//大的放下面,小的优先!!!!
}
};

int bfs(int x,int y){
memset(vis,0,sizeof(vis));
node ss;//把起点放进队列
ss.d=0;
ss.x=x;
ss.y=y;
priority_queue<node>q;
q.push(ss);
vis[ax][ay]=1;//放进去就标记已访问
while(!q.empty()){
node now=q.top();//每次取队顶进行扩展
q.pop();//取完pop
if(mp[now.x][now.y]=='r')return now.d;
for(int i=0;i<4;i++){//四个维度
int nx=now.x+dx[i];
int ny=now.y+dy[i];
if(nx<0||nx>=N||ny<0||ny>=M||mp[nx][ny]=='#'||vis[nx][ny])continue ;//越界或撞墙或已访问
node go;
go.x=nx;
go.y=ny;
go.d=now.d+1;
if(mp[nx][ny]=='x')go.d++;//遇到守卫加1
q.push(go);
vis[nx][ny]=1;//入队标记vis
}
}
return -1;//没找到路
}

int main()
{
while(~scanf("%d%d",&N,&M)){
for(int i=0;i<N;i++)
scanf("%s",mp[i]);
for(int i=0;i<N;i++){
for(int j=0;j<M;j++){
if(mp[i][j]=='a'){
ax=i;ay=j;break;
}
}
}
int ans=bfs(ax,ay);
if(ans==-1)printf("Poor ANGEL has to stay in the prison all his life.\n");
else printf("%d\n",ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: