标签:
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 14577 Accepted Submission(s): 4613
Special Judge
#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <queue> using namespace std; #define maxn 210 #define inf 0x3f3f3f3f3f3f char Map[maxn][maxn]; int visit[maxn][maxn]; int dir[4][2]={0,-1,0,1,-1,0,1,0}; int n,m; int pre_x[maxn][maxn],pre_y[maxn][maxn]; int rear_x[maxn][maxn],rear_y[maxn][maxn]; int cnt; struct node { int x,y,dist=0; }; struct cmp { bool operator () (node a,node b) { if(a.dist>b.dist) //从小到大排序 return true; else return false; } }; priority_queue <node,vector <node>,cmp> pq; void init() { cnt=1; memset(visit,0,sizeof(visit)); memset(pre_x,-1,sizeof(pre_x)); memset(pre_y,-1,sizeof(pre_y)); memset(rear_x,-1,sizeof(rear_x)); memset(rear_y,-1,sizeof(rear_y)); pre_x[0][0]=0; pre_y[0][0]=0; rear_x[n-1][m-1]=n-1; rear_y[n-1][m-1]=m-1; // for(int i=1;i<maxn;i++) // printf("%d",pre_x[i]); // printf("%d %d\n\n",pre_x[1],pre_y[1]); while(!pq.empty()) pq.pop(); } int bfs(node start) { pq.push(start); //值传递 node cur; visit[start.x][start.y]=1; while(!pq.empty()) { cur=pq.top(); pq.pop(); if(cur.x==n-1 && cur.y==m-1) { printf("It takes %d seconds to reach the target position, let me show you the way.\n",cur.dist); int father_x=cur.x,father_y=cur.y,xx,yy; while(pre_x[father_x][father_y]!=father_x || pre_y[father_x][father_y]!=father_y) { xx=father_x; yy=father_y; father_x=pre_x[xx][yy]; father_y=pre_y[xx][yy]; rear_x[father_x][father_y]=xx; rear_y[father_x][father_y]=yy; } int son_x=0,son_y=0; while(rear_x[son_x][son_y]!=son_x || rear_y[son_x][son_y]!=son_y) { printf("%ds:(%d,%d)->(%d,%d)\n",cnt++,son_x,son_y,rear_x[son_x][son_y],rear_y[son_x][son_y]); xx=son_x; yy=son_y; son_x=rear_x[xx][yy]; son_y=rear_y[xx][yy]; if(Map[son_x][son_y]!=‘.‘ && Map[son_x][son_y]!=‘X‘) for(int i=1;i<=(Map[son_x][son_y]-‘0‘);i++) printf("%ds:FIGHT AT (%d,%d)\n",cnt++,son_x,son_y); } printf("FINISH\n"); return 1; } for(int i=0;i<4;i++) { node next; int x,y; next.x=x=cur.x+dir[i][0]; next.y=y=cur.y+dir[i][1]; if(0<=x && x<n && 0<=y && y<m && visit[x][y]==0 && Map[x][y]!=‘X‘) //只被更新一次,与优先队列优化的Dijkstra的区别在于 //更新点到每个有可能更新它的点的权值是固定的,所以弹出来最短的点,然后更新,就是最短的。 //优先队列优化的Dijkstra,它多次被松弛的原因是在于弹出来的点是最短路径。但是 //更新点可能有多条路径到达更新点,假设更新点是最后一个点,那么倒数第二个点到这个更新点的权值不一样, //所以每条路径上的到倒数第二个点的最短路径加倒数第二个点与倒数第一个点的边的权值就可能会让更新点被多次更新 //然而如果在类似于hdu1026,这样的图中,由于更新点到每个有可能更新它的点的权值是固定的,所以 //只需要用到倒数第二个点的最短路径去更新它即可,从优先队列里弹出来的点就是到达每个点的最短路径, //所以只需要把bfs中的普通队列换成优先队列即可。 { if(Map[x][y]==‘.‘) { next.dist=cur.dist+1; pq.push(next); pre_x[next.x][next.y]=cur.x; pre_y[next.x][next.y]=cur.y; visit[next.x][next.y]=1; } else { int step=Map[x][y]-‘0‘+1; next.dist=cur.dist+step; pq.push(next); pre_x[next.x][next.y]=cur.x; pre_y[next.x][next.y]=cur.y; visit[next.x][next.y]=1; } } } } return 0; } int main() { // freopen("test.txt","r",stdin); while(~scanf("%d%d%*c",&n,&m)) { init(); for(int i=0;i<n;i++) { scanf("%s",Map[i]); } node start; start.x=0; start.y=0; start.dist=0; if(bfs(start)==0) printf("God please help our poor hero.\nFINISH\n"); } return 0; }
标签:
原文地址:http://www.cnblogs.com/xianbin7/p/4714938.html