首页 > 代码库 > hdu 5040 优先队列BFS+剪枝
hdu 5040 优先队列BFS+剪枝
(北京网络赛09题)题意:给一矩阵(图),里面有起点,终点,还有探照灯(每个有初始朝向,每秒顺时针转90度),前面有灯或者自己被灯照着,移动就要花3秒,求起点到终点最短时间。
用一个数组三维数组记录一下,用来当前位置当前时间%4有没有灯,然后优先队列(时间短的在前面),搜索即可。考虑到可以来回走或者原地等,不能简单判重剪枝:每个地方最多是4种状态!就是4秒之后就全图状态回到一样!所以若当前状态(时间%4)下来过就不用来了。
#include<iostream> #include<vector> #include<cstdio> #include<algorithm> #include<cstring> #include<string> #include<queue> #include<cmath> using namespace std; struct xy { int x,y; int times; bool operator <(const xy &ttt)const { return ttt.times<times; } }; int n; int a[505][505]; int b[505][505][4]; int vis[505][505][4]; int f[4][2]={-1,0,0,1,1,0,0,-1}; xy ss; int mints; void bfs() { priority_queue<xy>q; q.push(ss); while(!q.empty()) { xy cur=q.top(); q.pop(); if(a[cur.x][cur.y]==4&&cur.times<mints) { mints=cur.times;break; } xy next1=cur; next1.times=cur.times+1; if(vis[next1.x][next1.y][next1.times%4]==0) { vis[next1.x][next1.y][next1.times%4]=1; q.push(next1); } for(int i=0;i<4;i++) { xy next; next.x=cur.x+f[i][0]; next.y=cur.y+f[i][1]; if(next.x>=0&&next.y>=0&&next.x<n&&next.y<n&&a[next.x][next.y]!=0) { if(b[next.x][next.y][cur.times%4]==1||b[cur.x][cur.y][cur.times%4]==1) { next.times=cur.times+3; if(vis[next.x][next.y][next.times%4]==0) { vis[next.x][next.y][next.times%4]=1; q.push(next); } } else { next.times=cur.times+1; if(vis[next.x][next.y][next.times%4]==0) { vis[next.x][next.y][next.times%4]=1; q.push(next); } } } } } } int main() { int T; scanf("%d",&T);int cnt=1; while(T--) { scanf("%d",&n); memset(b,-1,sizeof(b)); memset(vis,0,sizeof(vis)); char tx;char sss[505]; for(int i=0;i<n;i++) { scanf("%s",sss); for(int j=0;j<n;j++) { tx=sss[j]; if(tx=='.') { a[i][j]=1; } else if(tx=='T') { a[i][j]=4; } else if(tx=='M') { a[i][j]=1; ss.x=i;ss.y=j; ss.times=0; } else if(tx=='#') { a[i][j]=0; } else if(tx=='N') { a[i][j]=2; for(int k=0;k<4;k++) { int xx=i+f[k][0]; int yy=j+f[k][1]; b[i][j][k]=1; if(xx>=0&&yy>=0&&xx<n&&yy<n) { b[xx][yy][k]=1; } } } else if(tx=='E') { a[i][j]=2; for(int k=0;k<4;k++) { int xx=i+f[k][0]; int yy=j+f[k][1]; b[i][j][k]=1; if(xx>=0&&yy>=0&&xx<n&&yy<n) { int ii=k; if(ii==0)ii=3; else ii--; b[xx][yy][ii]=1; } } } else if(tx=='S') { a[i][j]=2; for(int k=0;k<4;k++) { int xx=i+f[k][0]; int yy=j+f[k][1]; b[i][j][k]=1; if(xx>=0&&yy>=0&&xx<n&&yy<n) { int ii=k; if(ii==0||ii==1)ii=ii+2; else ii=ii-2; b[xx][yy][ii]=1; } } } else if(tx=='W') { a[i][j]=2; for(int k=0;k<4;k++) { int xx=i+f[k][0]; int yy=j+f[k][1]; b[i][j][k]=1; if(xx>=0&&yy>=0&&xx<n&&yy<n) { int ii=k; if(ii==3)ii=0; else ii++; b[xx][yy][ii]=1; } } } } } mints=0x3f3f3f3f; vis[ss.x][ss.y][ss.times]=1; bfs(); printf("Case #%d: ",cnt++); if(mints==0x3f3f3f3f) { printf("-1\n"); } else { printf("%d\n",mints); } } return 0; }
hdu 5040 优先队列BFS+剪枝
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。