P1825 [USACO11OPEN] Corn Maze S

  • P1825 Corn Maze S

    BFS,但是可以考虑最短路。

    需要注意的是传送门的处理,直接从当前点到传送门的终点建边即可,

    注意二维转一维时,数组要开到 N 2 N^2 N2

    #include <bits/stdc++.h>
    using namespace std;
    
    const int maxn=305;
    int a[maxn][maxn],N,M,dis[maxn*maxn],head[maxn*maxn],dx[4]={-1,0,0,1},dy[4]={0,-1,1,0},cnt,tot[50],c[50][5];
    struct edge{int to,w,nxt;}e[maxn*maxn*4];
    struct node
    {
        int id,d;
        bool friend operator < (node a,node b){return a.d>b.d;}
    };
    priority_queue<node> q;
    bool vis[maxn*maxn];
    
    void add(int x,int y,int z){e[++cnt]=(edge){y,z,head[x]},head[x]=cnt;}
    
    int getp(int x,int y){return (x-1)*M+y;}
    
    void dij(int s)
    {
        memset(dis,0x3f3f3f3f,sizeof dis);
        dis[s]=0;q.push((node){s,0});
        while(!q.empty())
        {
            int u=q.top().id;q.pop();
            if(vis[u]) continue;
            vis[u]=1;
            for(int i=head[u];i;i=e[i].nxt)
                if(dis[e[i].to]>dis[u]+e[i].w) dis[e[i].to]=dis[u]+e[i].w,q.push((node){e[i].to,dis[e[i].to]});
        }
    }
    
    int main()
    {
        cin>>N>>M;
        int ss=1,t=N*M;
        for(int i=1;i<=N;i++)
            for(int j=1;j<=M;j++)
            {
                char ch;cin>>ch;
                if(ch=='=') t=getp(i,j);
                else if(ch=='@') ss=getp(i,j);
                else if(ch=='#') a[i][j]=1e9;
                else if(ch>='A'&&ch<='Z') a[i][j]=ch-'A'+1,c[a[i][j]/*传送门编号*/][++tot[a[i][j]]/*传送门出现次数*/]=getp(i,j);
            }
        for(int i=1;i<=N;i++)
            for(int j=1;j<=M;j++) 
            {
                if(a[i][j]==1e9) continue;
                int p=getp(i,j);
                for(int k=0;k<4;k++)
                {
                    int nx=i+dx[k],ny=j+dy[k];
                    if(nx>=1&&nx<=N&&ny>=1&&ny<=M&&a[nx][ny]!=1e9)
                    {
                        if(a[nx][ny]>=1&&a[nx][ny]<=26&&tot[a[nx][ny]]>=2)
                        {
                            if(getp(nx,ny)==c[a[nx][ny]][1]) add(p,c[a[nx][ny]][2],1);
                            else add(p,c[a[nx][ny]][1],1);
                        }
                        else add(p,getp(nx,ny),1);
                    }
                }
            }
        dij(ss);
        cout<<dis[t];
        return 0;
    }
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值