这是往年校赛的一道题,最开始做这道题的时候还没有系统的学习过搜索,用了C语言学的回溯法尝试,毫无疑问的TLE;
学习了DFS之后,自己的剪枝功力不够,又是TLE,最后学了BFS之后,哇,终于做出来了,别提多开心了,然后意识到这道题其实很简单的,剋以用BFS标记法和更改步数法(更改最小消耗),后来发现这种题也可以建图跑迪杰斯特拉做;
BFS标记法:

#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>using namespace std;
const int N = 100 + 5;
int mat[N][N];
bool visit[N][N];
typedef struct node{int x,y,val;bool operator < (const node x)const {return val > x.val;}
}Node;
const int dir[4][2] = {{1,0},{-1,0},{0,1},{0,-1}};int BFS(int n){priority_queue<Node> Q;Node t;memset(visit,0,sizeof(visit));int x=0,y=0,goalx=n-1,goaly=n-1,newx,newy;t=(Node){x,y,mat[x][y]};visit[x][y] = true;Q.push(t);while(!Q.empty()){t = Q.top();Q.pop();if(t.x == goalx && t.y == goaly) return t.val;for(int d=0;d<4;d++){newx = t.x + dir[d][0];newy = t.y + dir[d][1];if(newx>=0 && newx<n && newy>=0 && newy<n && mat[newx][newy] && !visit[newx][newy]){visit[newx][newy] = true;Q.push((Node){newx,newy,t.val+mat[newx][newy]});}}}return -1;
}void Input_data(int n){for(int i=0;i<n;i++)for(int j=0;j<n;j++){scanf("%d",&mat[i][j]);}
}int main(){int n;while(scanf("%d",&n)==1){Input_data(n);printf("min=%d\n",BFS(n));}
}

BFS更改步数法:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>using namespace std;const int N = 100+5;
const int MaxSize = 1e5;
const int INF = (1<<30);
int mat[N][N];
int Min[N][N];
typedef struct node{int x,y,val;bool operator < (const node x) const {return val > x.val;}
}Node;
const int dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
int BFS(int n){priority_queue<Node> Q;int newx,newy,x=0,y=0,goalx= n-1,goaly=n-1;Node t,s;t.x = x,t.y = y,t.val = mat[0][0];Min[x][y] = mat[x][y];Q.push(t);while(true){t = Q.top();if(t.x == goalx && t.y == goaly ) return t.val;for(int d=0;d<4;d++){newx = t.x+dir[d][0];newy = t.y+dir[d][1];if(newx>=0 && newx<n && newy>=0 && newy<n && mat[newx][newy]){if(t.val + mat[newx][newy] < Min[newx][newy]){s.x = newx,s.y = newy,s.val = t.val+mat[newx][newy];Min[newx][newy] = s.val;Q.push(s);}}}Q.pop();}
}void Init(){for(int i=0;i<N;i++)for(int j=0;j<N;j++){Min[i][j] = INF;}
}void Input_data(int n){for(int i=0;i<n;i++)for(int j=0;j<n;j++)scanf("%d",&mat[i][j]);
}int main(){int n;//freopen("1.out","r",stdin);while(scanf("%d",&n)==1){Init();Input_data(n);printf("min=%d\n",BFS(n));}
}

建图跑迪杰斯特拉:

#include<iostream>
#include<cstring>
#include<cstdio>
#define _cp(a,b)((a.val)<(b.val))using namespace std;const int MAXN = 100000;
const int INF = (1<<30);
const int N = 100 + 5;
int mat[N][N],D[N*N];
bool visit[N*N];
int Size[N*N];
typedef struct node{short val,to;
}Node;
typedef Node elem_t;
Node edge[N*N][4];
const int dir[4][2]={{-1,0},{1,0},{0,1},{0,-1}};
void Init(){for(int i=0;i<N*N;i++){Size[i] = 0;visit[i] = false;D[i] = INF;}
}
void build_mat(int n){Node t;int to,newx,newy,from;for(int i=0;i<n;i++)for(int j=0;j<n;j++){from = i*n+j;for(int d=0;d<4;d++){newx = i + dir[d][0];newy = j + dir[d][1];if(newx>=0 && newx<n && newy>=0 && newy<n && mat[newx][newy]){to = newx*n+newy;int & cnt = Size[from];t.to = to,t.val=mat[newx][newy];edge[from][cnt++] = t;}}}
}
struct heap{elem_t h[MAXN];int n,p,c;void init(){n=0;}void ins(elem_t e){for(p=++n;p>1 && _cp(e,h[p>>1]);h[p]=h[p>>1],p>>=1);h[p] = e;}int del(elem_t &e){if(!n) return 0;for(e=h[p=1],c=2;c<n && _cp(h[c+=(c<n-1 &&_cp(h[c+1],h[c]))],h[n]);h[p] = h[c],p=c,c<<=1);h[p] = h[n--]; return 1;}
};
int DIJ(int n){heap H;H.init();D[0] = 0;Node t;int u,v;t.to = 0,t.val = 0;H.ins(t);while(H.del(t)){u = t.to;visit[u] = true;if(D[u] < t.val) continue;for(int j=0; j<Size[u]; j++){v = edge[u][j].to;if(visit[v]) continue;if(D[v] > D[u] + edge[u][j].val){D[v] = D[u] +edge[u][j].val;t.to = v,t.val = D[v];H.ins(t);}}}return D[n*n-1] + mat[0][0];
}
void Input_data(int n){for(int i=0;i<n;i++)for(int j=0;j<n;j++){scanf("%d",&mat[i][j]);}
}
int main(){int n;while(scanf("%d",&n)==1){Init();Input_data(n);build_mat(n);printf("min=%d\n",DIJ(n));}
}

双向BFS:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>using namespace std;const int N = 100+5;
const int MaxSize = 1e5;
const int INF = (1<<30);
int mat[N][N];
struct visit{int val,vis;
}Min[N][N];typedef struct node{int x,y,val;bool operator < (const node x) const {return val > x.val;
    }
}Node;const int dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}};int BFS(int n){priority_queue<Node> Q1,Q2;int newx,newy,cnt,x=0,y=0,goalx= n-1,goaly=n-1,ans = INF;Node t,s;t.x = x,t.y = y,t.val = mat[0][0];s.x = goalx,s.y = goaly,s.val = mat[goalx][goaly];Min[x][y].vis = 1,Min[x][y].val = mat[x][y];Min[goalx][goaly].vis = 2,Min[goalx][goaly].val = mat[goalx][goaly];Q1.push(t);Q2.push(s);while(!Q1.empty()|| !Q2.empty()){
    cnt = Q1.size();
    while(cnt--){        t = Q1.top(); Q1.pop();
        if(t.x == goalx && t.y == goaly ) ans = min(ans,t.val);         //这里一定要注意,要拓展完才能确定最小值,不能相遇就跳出
        for(int d=0;d<4;d++){            newx = t.x+dir[d][0];
            newy = t.y+dir[d][1];
            if(newx>=0 && newx<n && newy>=0 && newy<n){                if(Min[newx][newy].vis==2) ans = min(t.val + Min[newx][newy].val,ans);
                if(t.val + mat[newx][newy] < Min[newx][newy].val){                s.x = newx,s.y = newy,s.val = t.val+mat[newx][newy];
                Min[newx][newy].val = s.val;
                Min[newx][newy].vis = 1;
                Q1.push(s);
                }
            }
        }
    }cnt = Q2.size();
    while(cnt--){        t = Q2.top();Q2.pop();
        if(t.x == x && t.y == y) return t.val;
        for(int d=0;d<4;d++){            newx = t.x + dir[d][0];
            newy = t.y + dir[d][1];
            if(newx>=0 && newx<n && newy>=0 && newy<n ){                if(Min[newx][newy].vis==1) ans = min(t.val + Min[newx][newy].val,ans);
                if(t.val + mat[newx][newy] < Min[newx][newy].val){                    s.x = newx,s.y = newy,s.val = t.val + mat[newx][newy];
                    Min[newx][newy].val = s.val;
                    Min[newx][newy].vis = 2;
                    Q2.push(s);
                }
            }
        }
    }}return ans;
}void Init(){
    for(int i=0;i<N;i++)
        for(int j=0;j<N;j++){        Min[i][j].val = INF;
        Min[i][j].vis = 0;
        }
}void Input_data(int n){
    int val;
    for(int i=0;i<n;i++)
        for(int j=0;j<n;j++){        scanf("%d",&val);
        mat[i][j] = val?val:INF;
        }
}int main(){
    int n;
    //freopen("1.out","r",stdin);
    while(scanf("%d",&n)==1){    Init();
    Input_data(n);
    printf("min=%d\n",BFS(n));
    }
}
//如有错误,还请指出

在这几种方法里,双向BFS和迪杰斯特拉耗时都是12ms,比其他两种BFS耗时都短,虽然说在这里使用迪杰斯特拉有点大材小用的意味,但是这种方法也去可以应用到其他问题上

转载于:https://www.cnblogs.com/Pretty9/p/7347724.html

搜索专题:问题 E: 挑战ACM迷宫相关推荐

  1. HNUST 挑战ACM迷宫(DFS)

    题目描述 如下图所示的是一个由程序设计题目组成的ACM迷宫.迷宫的左上角是入口,右下角是出口.迷宫中每一个格子都有一个程序设计题目,挑战者要AC该题目后才能通过,大于0的数字表示AC该题目所需的最短时 ...

  2. 【寒假训练/Java】搜索专题

    文章目录 题目链接 知识点 题目列表 快输 A - Knight Moves(BFS/双向BFS) B - 迷宫(一) C - 迷宫(二)(BFS) D - 老子的全排列呢 E - [NOIP2002 ...

  3. 【蓝桥杯】搜索专题总结——真题讲解

    写在前面 小伙伴们我们又见面啦~这篇文章拖了又拖,终于写完啦.这篇讲了几道蓝桥杯中考察DFS和BFS的真题,大家可以去看看前面两篇文章,对搜索讲的很详细.[一万字]蓝桥杯算法竞赛备考(一)--搜索专题 ...

  4. 2019.6.7 一场搜索专题的考试【including 洛谷·血色先锋队,入门OJ·兴建高铁,珠光宝气阁

    这次分数还好.但全是搜索题还没上200就有点打击人了--[本狸才177QAQ 血色先锋队/血色敢死队 传送门:洛谷P1332 & 入门OJ P2259 Description 邪魔天国领主复活 ...

  5. 谷歌中国搜索业务再遇挑战

    昨日,Google全球副总裁.中国区总裁刘允,出席Google创想时空活动.新京报记者 周岗峰 摄 新京报讯 (记者刘夏)在中国市场艰难前行多年后,由搜索起家的Google开始转战中国移动广告市场.昨 ...

  6. 搜索专题——迷宫寻宝

    原题链接:FZU-2285 题目描述: 描述:洪尼玛今天准备去寻宝,在一个n*n (n行, n列)的迷宫中,存在着一个入口.一些墙壁以及一个宝藏.由于迷宫是四连通的,即在迷宫中的一个位置,只能走到与它 ...

  7. 深度优先搜索和广度优先搜索及典例分析(走迷宫问题(BFS)和棋盘问题(DFS))

    搜索算法在实际编程应用中起着举足轻重的作用,学会掌握搜索算法并熟练应用搜索算法来解决实际问题不得不说是一件相当COOL的事,所以我将深度搜索和广度搜索认真地做了详细的总结,与诸君共勉,也方便以后查阅复 ...

  8. 搜索入门之dfs--经典的迷宫问题解析

    今天来谈一下dfs的入门,以前看到的dfs入门,那真的是入门吗,都是把dfs的实现步骤往那一贴,看完是知道dfs的步骤了,但是对于代码实现还是没有概念.今天准备写点自己的心得,真的是字面意思--入门. ...

  9. 【搜索专题】DFS之连通性模型与搜索顺序

    内部搜索不用(能)回溯,外部搜索才需要(必须)回溯和恢复现场 A.AcWing 1112. 迷宫 内部搜索的一道dfs模板题,别忘了vis #include<cstdio> #includ ...

最新文章

  1. ubuntu 16.04 多个python版本切换
  2. [.net 面向对象编程基础] (13) 面向对象三大特性——多态
  3. 012-简单辅助元素
  4. 著名站点的爬虫 —— 豆瓣
  5. 三大linux系统对比
  6. ASP.NET控件开发基础5
  7. vue读取终端硬件信息_自助服务终端机主要特点及规格
  8. 30分钟快速上手Docker,看这篇就对了!
  9. Python的pyproject.toml文件中的tool.poetry.dev-dependencies选项
  10. 【转】No Persistence provider for EntityManager问题
  11. Android中的onWindowFocusChanged()方法详解
  12. 分区分服游戏框架设计
  13. GDC演讲翻译——看门狗2的载具同步
  14. 最新小学计算机课五年级上册目录,部编版小学语文教材2020最新调整!涉及20多篇课文!(附2020年教育部中小学生阅读指导目录)...
  15. lookup无序查找_excel无序查询 使用LOOKUP函数实现无序查询
  16. 红色警戒2修改器原理百科(七)
  17. win10专业版和企业版的区别
  18. 8421码到5421码的转换_8421BD码转换成5421BCD码.doc
  19. 一年前,没有Android,我还是一个游戏开发者
  20. 人工智能的三个层次:运算智能,感知智能,认知智能

热门文章

  1. ”舍得“大法:把自己的优点当缺点倒出去
  2. DLL技术应用04 - 零基础入门学习Delphi47
  3. 产品管理:孵化产品 Beta 流程
  4. Redhat change hostname
  5. J2EE项目移植问题一
  6. KVM虚拟化存储管理
  7. 四大中三家已面向客户推出机器人业务解决方案?别逗了,先用机器人自我革命吧! post by 上海嘉冰信息技术...
  8. 提高oracle查询效率
  9. MySQL技术内幕 InnoDB存储引擎 之 InnoDB体系架构
  10. 任务调度利器:Celery