01BFS:小明的游戏

普通的bfs:解决边权为1的最短路问题。从0的点开始往后更新,因为边权为1,所以呈现单调不递减的趋势。

第一次碰到的距离一定是最短距离,如果边权不相等,不一定是单调不递减趋势,第一次碰到的距离不一定是最短距离。

01BFS又称双端队列BFS

既有0,又有1,能不能用BFS来解决呢?在最短路问题中,边权值可能为1也可能为0。那么,在BFS的过程中,

  • 可以将边权为0 的扩展出来的点放到队首
  • 边权为1 扩展出来的点放到队尾

这样就能保证像普通BFS一样整个队列权值单调不下降。

相同的点可能会多次遇到,此时要进行松弛操作,比如从A->B,从A->C->E->B,这两条路线都能到达B,此时要判断哪一条的路线是最优解。

题目:P4554 小明的游戏 - 洛谷

cpp 复制代码
#include <iostream>
#include <deque> 
#include <cstring>

using namespace std;
const int N = 510;
typedef pair<int, int> PII;

int n, m;
int b1, b2, e1, e2;
char a[N][N];
int st[N][N];

int dx[] = {0, -1, 0, 1};
int dy[] = {1, 0, -1, 0};

int bfs()
{
	if (b1 == e1 && b2 == e2) return 0;
	
	deque<PII> q;
	memset(st, -1, sizeof(st));
	
	st[b1][b2] = 0;
	q.push_front({b1, b2});
	
	while(q.size())
	{
		auto t = q.front(); q.pop_front();
		int x1 = t.first, y1 = t.second;
		
		for (int i = 0; i < 4; i++)
		{
			int x2 = x1 + dx[i], y2 = y1 + dy[i];
			if (x2 < 1 || y2 < 1 || x2 > n || y2 > m) continue;
			
			int cnt = 0;
			if (a[x1][y1] == a[x2][y2]) 
			{
				cnt = 0;
			}
			else
			{
				cnt = 1;
			}
			
			if (st[x2][y2] == -1)//如果等于-1 
			{
				st[x2][y2] = st[x1][y1] + cnt;
				if (cnt == 0)
				{
					q.push_front({x2, y2});
				}
				else
				{
					q.push_back({x2, y2});
				}
			}
			else
			{
				if (st[x1][y1] + cnt < st[x2][y2])
				{
					st[x2][y2] = st[x1][y1] + cnt;
				}
			}
			
			if (x2 == e1 && y2 == e2) return st[e1][e2];
		}
	}
	
	return -1;
}

int main()
{	
	while(cin >> n >> m, n && m)
	{
		for (int i = 1; i <= n; i++)
		{
			for (int j = 1; j <= m; j++)
			{
				cin >> a[i][j];
			}
		}
		
		cin >> b1 >> b2 >> e1 >> e2;
		b1++, b2++, e1++, e2++;
		
		cout << bfs() << endl;
	}
	
	return 0;
}

为什么第一次走到的一定是最短路径?边权不是0和1吗?

0-1 BFS(双端队列BFS)的核心性质保证了这一点:

队列的单调性

  • 在0-1 BFS中,我们使用双端队列(deque)
  • 当边权为0时,节点放入队首
  • 当边权为1时,节点放入队尾

这样的操作保证了队列中的距离值(st值)是单调不递减的

相关推荐
wabs6661 小时前
关于贪心算法的一些自我总结【力扣45.跳跃游戏II】【灵感来源:代码随想录】
算法·贪心算法·复盘
2401_876964131 小时前
【湖北专升本】2026湖北专升本真题PDF+备考资料汇总
数据结构·人工智能·经验分享·深度学习·算法·计算机视觉
嗝o゚2 小时前
CANN GE 算子融合——融合算法与调度策略
算法·昇腾·cann·ge
小江的记录本2 小时前
【JVM虚拟机】垃圾回收GC:垃圾回收算法:标记-清除、标记-复制、标记-整理、分代收集(附《思维导图》+《面试高频考点清单》)
java·jvm·后端·python·算法·安全·面试
Ulyanov4 小时前
用声明式语法重新定义Python桌面UI:QML+PySide6现代开发入门(一)
开发语言·python·算法·ui·系统仿真·雷达电子对抗仿真
数据科学小丫4 小时前
特征工程处理
人工智能·算法·机器学习
z落落4 小时前
C#参数区别
java·算法·c#
c238565 小时前
vector(下)
数据结构·算法
z落落5 小时前
C# 冒泡排序+选择排序 + Array.Sort 自定义排序
数据结构·算法
wyy185100737285 小时前
双路并行:一套匹配算法如何解决中文制单的两大核心难题
算法·ai·crm·crm系统