[HDU] 1026 Ignatius and the Princess I 简单建模后广搜索求最短路径生成树

题目链接:

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");
    }
}

 

posted @ 2013-04-16 13:47  kbyd  阅读(175)  评论(0编辑  收藏  举报