题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=1026
方法:状态搜索树的节点保存4个东西,坐标x,y,当前总共耗时,其最短路径前驱指针。当前节点根绝自身情况计算出耗时,然后加上前面一个节点累计的耗时得到当前到该节点使用的耗时,配合使用用当前累计时间排序的优先队列使用dijkstra算法原理。
感想:图论dijkstra算法,熟悉其证明方法。
代码:
View Code
#include <iostream> #include <queue> #include<stack> using namespace std; int row,col; char trap ='X'; char road ='.'; char map[101][101]; bool visited[101][101]; int direction[4][2] ={{0, -1}, {-1, 0}, {0, 1}, {1, 0}}; struct point { int x,y,currentStep; point* last; }; struct pointCmp { bool operator()(const point* p1,const point* p2) { return p1->currentStep>p2->currentStep; } }; bool canGo(int x ,int y) { if(x<1||x>row||y<1||y>col) return false; return !visited[x][y]; } stack<point* > pointStack; point* search() { point* cur = (point*) malloc(sizeof(point)); point* result =NULL; cur->x = 1; cur->y = 1; cur->currentStep = 0; cur->last = NULL; priority_queue<point*,vector<point*>,pointCmp> Q; Q.push(cur); while(!Q.empty()) { cur = Q.top(); Q.pop(); if( visited[cur->x][cur->y]!=true) { visited[cur->x][cur->y] = true; if(cur->x == row && cur->y == col) { result = cur; while(cur!=NULL) //找到后居然要用堆栈保存 不用堆栈保存还要错 我不知道我用链表到底问题在哪里 恶心 { pointStack.push(cur); cur=cur->last; } break; } else { for(int i=0;i<4;i++) { int x=cur->x+direction[i][0]; int y=cur->y+direction[i][1]; if(canGo(x,y)) { point* newCur = (point*) malloc(sizeof(point)); newCur->x=x; newCur->y=y; newCur->last=cur; newCur->currentStep=cur->currentStep+(map[newCur->x][newCur->y]==road ? 1:1+map[newCur->x][newCur->y]-48); Q.push(newCur); } } } } } return result; } void main() { while( scanf("%d %d",&row,&col)!= EOF ) { for(int i = 1;i<=row;i++) for(int j=1;j<=col;j++) { cin>>map[i][j]; if(map[i][j] == trap) visited[i][j]=true; else visited[i][j] = false; } point* result = search(); if(result == NULL) puts("God please help our poor hero."); else { int totalSteps = result->currentStep; printf("It takes %d seconds to reach the target position, let me show you the way.\n",totalSteps); for (int i=1,cnt=1;cnt<=totalSteps;cnt++,i++) //用这种方式从堆栈中还原路径 { point* tempPoint=pointStack.top(); pointStack.pop(); point* currentPoint=pointStack.top(); printf("%ds:(%d,%d)->(%d,%d)\n",cnt,tempPoint->x-1,tempPoint->y-1,currentPoint->x-1,currentPoint->y-1); char a=map[currentPoint->x][currentPoint->y]; if(a!='.') for (int k=0;k<a-'0';k++) { cnt++; printf("%ds:FIGHT AT (%d,%d)\n",cnt,currentPoint->x-1,currentPoint->y-1); } } pointStack.pop(); } puts("FINISH"); } }