多校第一场:hdu 4308(bfs)

本文介绍了一种解决迷宫最短路径问题的算法实现,使用BFS(宽度优先搜索)来寻找从起点Y到终点C的最短路径。地图中包含不可通行障碍物#、传送门P以及特殊节点*,后者需支付费用通过。传送门视为同一节点,简化路径计算。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最短路。
给出的地图中,Y为起点,C为终点,#点不能通过,可直接忽略。所有的P为互通的传送门,故可将所以的P看作同一个点。每个能通过的点可以向上下左右四个方向走,如果对应的方向可以通过,则连边,若要走到的点是*,则边权为通过的费用,否则边权为0。
连边后求Y到C的最短路即可。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
//int dir[4][2]={{-1,0},{0,1},{1,0},{0,-1}};
int vis[300][300];
int map[300][300];
int xx[] = {0, 0, 1, -1};
int yy[] = {1, -1, 0, 0};


struct Node
{
    int rr,cc;
};


Node p[300*300];


Node ed;


struct poi
{
    int rr,cc;
    int val;
};


poi start;
int r,c,v;
int k;


int inmap(int r1,int c1)
{
    if(r1>=1&&r1<=r&&c1>=1&&c1<=c)
    return 1;
    else
    return 0;
}


int bfs(poi s)
{
   queue<poi>qu;
   while(!qu.empty())
     qu.pop();


   qu.push(s);
   vis[s.rr][s.cc]=1;
   int ans=-1;
   while(!qu.empty())
   {
     poi cur,nex;
     cur=qu.front();
     qu.pop();
     if(cur.rr==ed.rr&&cur.cc==ed.cc)
     {
         ans=cur.val;
         break;
     }
     for(int i=0;i<4;i++)
     {
         nex.rr=cur.rr+xx[i];
         nex.cc=cur.cc+yy[i];
             if(!inmap(nex.rr,nex.cc)||vis[nex.rr][nex.cc]||!map[nex.rr][nex.cc])
             continue;
             else if(map[nex.rr][nex.cc]==2)
             {
                 for(int j=0;j<k;j++)
                 {
                     nex.rr=p[j].rr;
                     nex.cc=p[j].cc;
                     nex.val=cur.val;
                     vis[p[j].rr][p[j].cc]=1;
                     qu.push(nex);
                 }
             }
            else
             {
                 nex.val=cur.val+1;
                 vis[nex.rr][nex.cc]=1;
                 qu.push(nex);
             }
     }
   }
   return ans;
}


int main()
{
    char ch;
  while(scanf("%d%d%d",&r,&c,&v)!=EOF)
  {
    k=0;
    memset(vis,0,sizeof(vis));
    memset(map,0,sizeof(map));
    for(int i=1;i<=r;i++)
    {
        for(int j=1;j<=c;j++)
        {
            cin>>ch;
            if(ch=='Y')
            {start.rr=i;start.cc=j;start.val=0;map[i][j]=1;}
            if(ch=='C')
            {ed.rr=i;ed.cc=j;map[i][j]=1;}
            if(ch=='#')
            map[i][j]=0;
            if(ch=='P')
            {p[k].rr=i;p[k].cc=j;k++;map[i][j]=2;}
            if(ch=='*')
            map[i][j]=1;
        }
        getchar();
    }
    int ans=bfs(start);
    
    if(ans != -1)
    printf("%d\n", (ans - 1) * v);
    else
    printf("Damn teoy!\n");


  }
  return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值