• 「题解」:走格子


    问题: 走格子

    时间限制: 1 Sec  内存限制: 256 MB

    题面


    题面谢绝公开

    题解


    嗯,长见识了。原来网格图也可以建建边跑最短路。

    考试的时候一直在想:怎么dfs的同时记录可以从哪个墙到哪个格子。

    最后想出来一种美妙方案,传上十一二个参数应该就行了吧,然后果断放弃。

    最后发现,只需要bfs预处理上几个数组就完美解决了……最后建边跑堆优化dijkstra就可以。

    之前一直对堆优化的迪杰不感冒,觉得跟不加堆优化差不到哪里去。

    然而……

    普通dijkstra

     

    堆优化dijkstra

    嗯中间还改了一点点小错误但是9420和666差的有点远了吧喂!

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<queue>
    #include<stack>
    #include<cmath>
    #include<algorithm>
    #define int long long
    #define rint register int
    using namespace std;
    int n,m,st,en,to_w[503][503],dist[503*503];
    int l_w[503][503],r_w[503][503],u_w[503][503],d_w[503][503];
    char str[503];
    bool v[503*503],map[503][503];
    struct node{int x,y;};
    struct node2{int u,v,w,nxt;}edge[503*503*64];
    int tot,first[503*503];
    queue <node> q;
    priority_queue<node> QAQ;
    bool operator < (node a,node b){return a.y>b.y;}
    inline void add(int uu,int vv,int ww)
    {
        ++tot;edge[tot].u=uu;edge[tot].v=vv;
        edge[tot].w=ww;edge[tot].nxt=first[uu];
        first[uu]=tot;
    }
    inline void bfs(){
        while(q.size()){
            rint x=q.front().x,y=q.front().y;q.pop();
            if(map[x+1][y]&&(!to_w[x+1][y])){to_w[x+1][y]=to_w[x][y]+1;q.push((node){x+1,y});}
            if(map[x][y+1]&&(!to_w[x][y+1])){to_w[x][y+1]=to_w[x][y]+1;q.push((node){x,y+1});}
            if(map[x-1][y]&&(!to_w[x-1][y])){to_w[x-1][y]=to_w[x][y]+1;q.push((node){x-1,y});}
            if(map[x][y-1]&&(!to_w[x][y-1])){to_w[x][y-1]=to_w[x][y]+1;q.push((node){x,y-1});}
        }
    }
    inline void dij()
    {
        for(rint i=1;i<=n*m;i++) dist[i]=0x7fffffff;
        dist[st]=0; QAQ.push((node){st,dist[st]});
        while(!QAQ.empty())
        {
            int x=QAQ.top().x,y=QAQ.top().y; 
            QAQ.pop();
            if(y>dist[x]) continue;
            for(rint i=first[x];i;i=edge[i].nxt)
            {
                int to=edge[i].v,w=edge[i].w;
                if(dist[to]>dist[x]+w)
                {
                    dist[to]=dist[x]+w;
                    QAQ.push((node){to,dist[to]});
                }
            }
        }    
    }
    signed main()
    {
        scanf("%lld %lld",&n,&m);
        for(rint i=1;i<=n;++i)
        {
            scanf("%s",str+1);
            for(rint j=1;j<=m;++j)
            {
                if(str[j]=='#')map[i][j]=0,q.push((node){i,j});
                if(str[j]=='C')st=(i-1)*m+j,map[i][j]=1;
                if(str[j]=='F')en=(i-1)*m+j,map[i][j]=1;
                if(str[j]=='.')map[i][j]=1;
            }
        }
        bfs();
        for(rint i=1;i<=n;++i)
            for(rint j=1;j<=m;++j)
                if(map[i][j])
                {
                    if(!map[i][j-1])l_w[i][j]=(i-1)*m+j;
                    else l_w[i][j]=l_w[i][j-1];
                    if(!map[i-1][j])u_w[i][j]=(i-1)*m+j;
                    else u_w[i][j]=u_w[i-1][j];
                }
        for(rint i=n;i>=1;--i)
            for(rint j=m;j>=1;--j)    
                if(map[i][j])
                {
                    if(!map[i][j+1])r_w[i][j]=(i-1)*m+j;
                    else r_w[i][j]=r_w[i][j+1];
                    if(!map[i+1][j])d_w[i][j]=(i-1)*m+j;
                    else d_w[i][j]=d_w[i+1][j];
                }
        for(rint i=1;i<=n;i++)
            for(rint j=1;j<=m;j++)
                if(map[i][j])
                {
                    int pos=(i-1)*m+j;
                    if(map[i][j+1])add(pos,pos+1,1),add(pos+1,pos,1);
                    if(map[i+1][j])add(pos,i*m+j,1),add(i*m+j,pos,1);
                    if(l_w[i][j]!=pos)add(pos,l_w[i][j],to_w[i][j]);
                    if(r_w[i][j]!=pos)add(pos,r_w[i][j],to_w[i][j]);
                    if(u_w[i][j]!=pos)add(pos,u_w[i][j],to_w[i][j]);
                    if(d_w[i][j]!=pos)add(pos,d_w[i][j],to_w[i][j]);
                }
        dij();
        if(dist[en]>=0x7fffffff){cout<<"no"<<endl;return 0;}
        printf("%lld
    ",dist[en]);
        return 0;
    }
    View Code
  • 相关阅读:
    聊聊高并发(二十四)解析java.util.concurrent各个组件(六) 深入理解AQS(四)
    java.lang.NoSuchMethodException: org.apache.catalina.deploy.WebXml addServlet
    理解Linux系统中的load average
    启动loadrunner 11的controller提示试图执行系统不支持的操作(已解决)
    linux系统瓶颈分析(精)
    常用的linux系统监控命令
    Loadrunner中Throughput(吞吐量)的分析与计算
    Lr_debug_message,Lr_output_message,Lr_error_message,Lrd_stmt,Lrd_fetch
    Loadrunner日志设置与查看
    LoadRunner中进程运行和线程运行区别
  • 原文地址:https://www.cnblogs.com/xingmi-weiyouni/p/11319629.html
Copyright © 2020-2023  润新知