bfs--hdoj1026(打印路径)

做了一下午,首先是栈溢出,由于没有把数组开在全局,然后是无限wa啊,就是没找出到底哪错了。

这道题计算最小时间不是难点,打印路径才是难点,我是在结构体中加了指向前一个结点变量,最后再循环找点。做完之后看了人家的代码,使用栈做的。

AC代码:

//1275771 2009-04-16 07:46:26 Accepted 1026 62MS 652K 2425 B C++ Xredman 
#include <iostream>
#include <queue>
#include <stack>
using namespace std;

const int N = 102;

typedef struct
{
    int x,y;
    int cost;
    int prex,prey;
}Node;

int dir[4][2] = {{-1, 0},{1, 0},{0, -1},{0, 1}};
int m, n;
Node path[N][N];
char graph[N][N];


void init()
{
    int i, j;
    for(i = 0; i < m; i++)
        cin>>graph[i];
    for(i = 0; i < m; i++)
        for(j = 0; j < n; j++)
            path[i][j].cost = -1;
}

bool isBound(int x,int y)
{
    if(x < 0 || y < 0)
        return false;
    if(x >= m || y >= n)
        return false;
    return true;
}

void bfs()
{
    queue<Node> Q;
    Node a, b;
    a.x = 0; a.y = 0; a.cost = 0;
    a.prex = 0; a.prey = 0;
    if(graph[0][0] != '.')
        a.cost = graph[0][0] - '0';
    path[0][0] = a;

    Q.push(a);
    while(!Q.empty())
    {
        a = Q.front();
        Q.pop();
        for(int i = 0; i < 4; i++)
        {
            b.x = a.x + dir[i][0];
            b.y = a.y + dir[i][1];
            if(!isBound(b.x, b.y))
                continue;
            if(graph[b.x][b.y] == 'X')
                continue;
            if(graph[b.x][b.y] == '.')
                b.cost = a.cost + 1;
            else
                b.cost = a.cost + graph[b.x][b.y] - '0' + 1;
            if(b.cost < path[b.x][b.y].cost || path[b.x][b.y].cost == -1)
            {
                b.prex = a.x; b.prey = a.y;
                path[b.x][b.y] = b;
                Q.push(b);
            }
        }
    }
    if(path[m - 1][n - 1].cost == -1)
    {
        cout<<"God please help our poor hero."<<endl;
        cout<<"FINISH"<<endl;
        return ;
    }
    stack<Node> S;
    int cc = 1, tmp;

    cout<<"It takes "<<path[m - 1][n - 1].cost<<" seconds to reach the target position, let me show you the way."<<endl;
    a = path[m - 1][n - 1];
    while(1)
    {
        if(a.x == 0 && a.y == 0)
            break;
        S.push(a);
        a = path[a.prex][a.prey];
    }
    
    a = path[0][0];

    while(!S.empty())
    {
        b = S.top();
        S.pop();
        if(graph[b.x][b.y] == '.')
            cout<<cc++<<"s:("<<a.x<<","<<a.y<<")->("<<b.x<<","<<b.y<<")"<<endl;
        else
        {
            cout<<cc++<<"s:("<<a.x<<","<<a.y<<")->("<<b.x<<","<<b.y<<")"<<endl;
            tmp = graph[b.x][b.y] - '0';
            while(tmp--)
                cout<<cc++<<"s:FIGHT AT ("<<b.x<<","<<b.y<<")"<<endl;
        }
        a = b;
    }
    cout<<"FINISH"<<endl;
}

int main()
{
    while(cin>>m>>n)
    {
        init();
        bfs();
    }
    return 0;
}


 

下面是我的代码,也请大家帮忙指导一下:

#include<iostream>
#include<cstring>
#include<cstdio>
#include<climits>
using namespace std;
int map[105][105];
int vis[105][105];
int n,m;
int ans;
int dx[]= {0,0,1,-1};
int dy[]= {1,-1,0,0};
struct A
{
    int x,y,tim;
    int prex,prey;
};
A queue[20000];
void bfs()
{
    int head=0,tail=1;
    A a,result;
    int flag=0;
    a.x=n-1,a.y=m-1,a.tim=map[a.x][a.y];
    a.prex=-1;
    a.prey=-1;
    queue[head]=a;
    while(head<tail)
    {
        a=queue[head++];
        if(a.x==0&&a.y==0)
        {
            if(ans>a.tim)
            {
                ans=a.tim;
                result=a;
            }
            flag=1;
        }
        for(int i=0; i<4; i++)
        {
            A b;
            b.x=a.x+dx[i];
            b.y=a.y+dy[i];
            if(b.x>=0&&b.x<n&&b.y>=0&&b.y<m&&(map[b.x][b.y]!=-1))
            {

                if(map[b.x][b.y]>0&&((a.tim+map[b.x][b.y]+1)<vis[b.x][b.y]))
                    b.tim=a.tim+map[b.x][b.y]+1;
                else if(a.tim+1<vis[b.x][b.y])
                    b.tim=a.tim+1;
                else
                    continue;
                vis[b.x][b.y]=b.tim;
                b.prex=a.x;
                b.prey=a.y;
                queue[tail++]=b;
            }
        }
    }
    if(flag)
    {
        A p=result;
        int k=1;
        head=head-1;
        int prx=p.x,pry=p.y;
        cout<<"It takes "<<p.tim<<" seconds to reach the target position, let me show you the way."<<endl;
        while(k<=ans)
        {
            if(map[prx][pry]==0)
            {
                cout<<k++<<"s:("<<prx<<","<<pry<<")->("<<p.prex<<","<<p.prey<<")"<<endl;
                prx=p.prex;
                pry=p.prey;
                while(((queue[head].x!=prx)||(queue[head].y!=pry)))
                {
                    head--;
                }
                p=queue[head];
            }
            else
            {
                for(int i=1; i<=map[prx][pry]; i++)
                    cout<<k++<<"s:FIGHT AT ("<<prx<<","<<pry<<")"<<endl;
                map[prx][pry]=0;
            }

        }
        cout<<"FINISH"<<endl;
    }
    else
        cout<<"God please help our poor hero."<<endl<<"FINISH"<<endl;

}
int main()
{
    //freopen("in.txt","r",stdin);
    char x;
    while(cin>>n>>m)
    {
        memset(map,-1,sizeof(map));
        memset(queue,0,sizeof(queue));
        ans=10000;
        for( int i=0; i<n; i++)
            for(int j=0; j<m; j++)
            {
                cin>>x;
                if(x=='.')
                    map[i][j]=0;
                if(x>='1'&&x<='9')
                    map[i][j]=x-'0';
        vis[i][j]=INT_MAX;
            }
            //vis[n-1][m-1]=0;
        bfs();
    }
    return 0;
}


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值