题目链接
- 博客主页: https://blog.csdn.net/qq_50285142
- 欢迎点赞收藏✨关注❤留言 如有错误,敬请指正
- 虽然生活很难,但我们也要一直走下去
思路:
使用双端队列解决边权值只有0和1的图的问题
如果某边的权值为1,则加入队尾
如果某边的权值为0,则加入队首,优先选择边权值为0的节点进行扩展
本题的思想类似于dijkstra算法,维护两个集合,一个是已经找到最小距离的集合,另一个是最小距离的点的扩展的集合。
双端队列中的点都是待扩展的点的集合,而出队的点就是找到最小距离的点的集合,故只要点一出队,那么这个点的最小距离就确定了。
四个坐标的解释:
s[] = "\/\/"
代表左上,右上,右下,左下四个方向的我们设置的默认路径,‘’为转义符,需要两个‘’才可以
dx[]={-1,-1,1,1},dy[]={-1,1,1,-1};
代表从当前点走到左上右上右下左下的四个方向的对角的点的坐标变化
ix[]={-1,-1,0,0},iy[]={-1,0,0,-1};
代表左上,右上,右下,左下四个方向的对应的方格的路径,默认每个方格的路径用该方格左上的角的点进行表示
默认每个点的距离为无穷大,先设置(0,0)点的距离为0,以(0,0)点进行扩展,不断寻找最短路径
#include往期优质文章推荐#define fi first #define se second using namespace std; typedef pair pii; const int N = 505,M = 505; const int dx[]={-1,-1,1,1},dy[]={-1,1,1,-1}; const int ix[]={-1,-1,0,0},iy[]={-1,0,0,-1}; char g[N][M]; int n,m; int dis[N][M]; bool st[N][M]; int bfs() { memset(dis,0x3f,sizeof dis); memset(st,false,sizeof st); char s[] = "\/\/"; deque q; dis[0][0] = 0; q.push_front({0,0}); while(!q.empty()) { pii t = q.front(); q.pop_front(); if(st[t.fi][t.se]) continue; st[t.fi][t.se] = true; for(int i=0;i<4;i++) { int nx = t.fi + dx[i]; int ny = t.se + dy[i]; if(nx<0 or nx>n or ny<0 or ny>m) continue; int xx = t.fi + ix[i],yy = t.se + iy[i]; int w = 0; if(g[xx][yy]!=s[i]) w = 1; if(dis[nx][ny] > dis[t.fi][t.se] + w) { dis[nx][ny] = dis[t.fi][t.se] + w; if(w) q.push_back({nx,ny}); else q.push_front({nx,ny}); } } } return dis[n][m]; } void solve() { cin>>n>>m; for(int i=0;i >g[i]; int d = bfs(); if(d==0x3f3f3f3f) cout<<"NO SOLUTIONn"; else cout< >_; while(_--) { solve(); } return 0; }
- C++ STL详解,超全总结(快速入门STL)
- 李【期末复习】c++知识点大回顾,八篇文章让你永不破防(一)
- 区间贡献问题习题详解



