图的搜索问题,是给出一个抽象的字符矩阵代表一张图,根据根据题目要求,对图进行搜索,关于搜索算法:点击这里
根据搜索方法的不同,分为深度优先遍历(DFS)、广度优先遍历(BFS),两者时间复杂度都是 O(N*N),通常采用深度优先遍历。
图的深度优先遍历的基本过程为:
其基本框架为:
int vis[N];
void DFS(int i) {
for(所有i的邻接点j) {
if(!vis[j]) {
if(j == 目标状态)
return true;
vis[j]=true;
dfs(j);
}
}
}
图的广度优先遍历的基本过程为:
其基本框架为:
bool vis[N];
void BFS(int start) {
queue Q;
Q.push(start);
vis[s]=true;
while(!Q.empty()) {
int x=Q.front();
Q.pop();
if(x==目标状态) {
...
}
for(所有i的邻接点j) {
if(!vis[j]) {
Q.push(j);
vis[j]=true;
}
}
}
}
对于给出的字符矩阵,在搜索过程中,利用奇偶剪枝能极大的降低时间复杂度。
假设起点为(sx,sy),终点为(ex,ey),给定 t 步恰好走到终点,如图所示(“|”竖走,“—”横走,“+”转弯),易证 abs(ex-sx)+abs(ey-sy) 为此问题类中任意情况下,起点到终点的最短步数,记做 step,此处 step1=8;
如图,为一般情况下非最短路径的任意走法举例,step2=14;step2-step1=6,偏移路径为 6
推广:若 t-[abs(ex-sx)+abs(ey-sy)] 结果为奇数,则无法在 t 步恰好到达,返回 false;反之,若结果为偶数,则可以在 t 步恰好到达,返回 true。
如图,没障碍物#时,S到E的最短路长为6,但是当有障碍物时,就要绕行了。
如图,黑色为最短路径,当他绕行(红色加蓝色部分)时,其中蓝色部分其实还是最短路径部分平移来的,所以多走的步数也就是红色部分。对于红色部分我们可以分为两部分,一部分是远离最短路径的步数,另一部分是回到最短路径的部分,他们一定是对称的,所以多走的步数一定是偶数。
所以,当问走 x 步能否到达 e,就算出最短路径长 y,如果 x-y 是偶数就能到达,否则不能到达。