問題省略…
思路:讓小哼往右邊走,直到走不通的時候再回到這裡,再去嘗試另乙個方向。規定乙個順序,按順時針方向來嘗試(即按照右、下、左、上的順序去嘗試)。
先
檢查小哼是否已經到達小哈的位置,如果沒有到達則找出下一步可以走的地方。為了解決這個問題,此處dfs()函式只需要維護3個引數,分別是x座標、y座標、以及當前已經走過的步數step。dfs函式定義如下:
void dfs(int x,int y,int step)
判斷是否已經到達小哈位置,只需要判斷當前的座標和小哈的座標是否相等即可,如果相等則表明已經到達小哈的位置,如下:
void dfs(int x,int y,int step)
return;
}
int next[4][2]=,//向右
,//向下
,//向左
};//向上
};
通過這個方向陣列,使用迴圈就很容易獲得下一步的座標。此處將下一步的橫座標用tx儲存,左邊用ty儲存。
for(int k=0;k<=3;k++)
接下來要對tx、ty進行一些判斷。包括是否越界、是否為障礙物,以及這個點是否已經在路徑中(避免重複訪問乙個點)。需要用book[tx][ty]來記錄格仔(tx,ty)是否已經在路徑中。
如果這個點符合所有要求,就對這個點進行下一步的擴充套件,即dfs(tx,ty,step+1).注意,此處的step+1,因為一旦從這個點開始繼續往下嘗試,意味著你的步數已經增加1.
for(int k=0;k<=3;k++)
}
完整**:
#include#includeusing namespace std;
int a[51][51],book[51][51];
int n,m,p,q,minn=99999999;
void dfs(int x,int y,int step) ,//向右
,//向下
,//向左
};//向上
//判斷是否到達小哈位置
if(x==p && y==q)
int tx,ty;
for(int k=0;k<=3;k++)
} return ; }
int main() ;
struct note que[2501];
int head,tail;
int a[51][51]=;//用來儲存地圖
int book[51][51]=;//作用是記錄哪些點已經佇列中,防止乙個點被重複拓展,全部初始化為0
//最開始需要進行初始化,即將佇列設定為空
head=1;
tail=1;
que[tail].x=1;
que[tail].y=1;
que[tail].s=0;
tail++;
book[1][1]=1;
}
然後從(1,1)開始,先嘗試往右走到達(1,2)。
tx=que[head].x;
ty=que[head].y+1;
需要判斷(1,2)是否越界。
//判斷是否越界
if(tx<1 || tx>n || ty<1 || ty>m)
continue;
再判斷(1,2)是否為障礙物或者已經在路徑中
//判斷是否為障礙物 或者已經在路徑中
if(a[tx][ty]==0 && book[tx][ty]==0)
若滿足上述兩個條件,則將(1,2)入隊,並標記該點已經走過。
book[tx][ty]=1; //把這個點標記為走過,注意寬搜每個點只入列一次,所以和深搜不同,不需要將book陣列還原
//插入新的點到佇列中
que[tail].x=tx;
que[tail].y=ty;
que[tail].s=que[head].s+1;
tail++;
接下來還有繼續嘗試其他方向走。此處規定乙個順序,即按照順時針方向來嘗試(也就是以右下左上順序嘗試)。發現從(1,1)還是可以到達(2,1),因此 也需要將(2,1)也加入佇列,實現**與剛才一樣。
對(1,1)拓展完畢後,(1,1)對我們已經沒有用,此時將(1,1)出隊。出隊操作,即:
head++;
接下來需要在新拓展出的(1,2)和(2,1)這兩點的基礎上繼續向下探索。到目前為止已經拓展出從起點出發一步以內可以到達的所有點。因為還沒有到達小哈的位置,所以繼續。直至走到小哈位置,演算法結束、
完整**:
#include#includeusing namespace std;
struct note ;
int main() ,book[51][51]=;
//定義乙個用於表示走的方向的陣列
int next[4][2]=,//向右
,//向下
,//向左
};//向上
int k,n,m,tx,ty,flag;
cin>>n>>m;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
cin>>a[i][j];
int startx,starty,p,q;
cin>>startx>>starty>>p>>q;
//佇列初始化
int head,tail;
head=1;
tail=1;
//往佇列插入迷宮入口座標
que[tail].x=startx;
que[tail].y=starty;
que[tail].f=0;
que[tail].s=0;
tail++;
book[startx][starty]=1;
flag=0;//用來標記是否到達目標點,0表示暫時沒有到達,1表示到達
while(headn || ty<1 || ty>m)
continue;
//判斷是否為障礙物 或者已經在路徑中
if(a[tx][ty]==0 && book[tx][ty]==0)
if(tx==p &&ty==q)
} if(flag==1)
break;
head++;//此地方不能忘記,當乙個點拓展結束,head++才能對後面的點再進行拓展
} //列印佇列中末尾最後乙個點(目標點)的步數
//注意tail是指向佇列隊尾(即最後一位)的下乙個位置,所以這需要-1
printf("%d",que[tail-1].s);
getchar();getchar();
return 0;
}
節選自《啊哈,演算法》這一本書,作者啊哈 廣度優先搜尋 深度優先搜尋
前言 這幾天複習圖論演算法,覺得bfs和dfs挺重要的,而且應用比較多,故記錄一下。廣度優先搜尋 有乙個有向圖如圖a 圖a廣度優先搜尋的策略是 從起始點開始遍歷其鄰接的節點,由此向外不斷擴散。1.假設我們以頂點0為原點進行搜尋,首先確定鄰接0的頂點集合s0 2.然後確定頂點1的集合s1 頂點2沒有鄰...
廣度優先搜尋,深度優先搜尋
深度優先搜尋 depth first search 簡稱dfs。最直觀的例子就是 走迷宮 廣度優先搜尋 每個頂點都要進出一遍佇列,每個邊也都會被訪問一次,所以 時間複雜度o v e 主要消耗記憶體的是visited prev陣列 queue佇列,所以 空間複雜度o v 深度優先搜尋 每條邊最多會被訪...
深度優先搜尋 廣度優先搜尋
深度優先搜尋 廣度優先搜尋 通過鄰接矩陣對圖進行深搜和廣搜 package com.neusoft.data.structure 深度優先搜尋 廣度優先搜尋 通過鄰接矩陣對圖進行深搜和廣搜 public class dfsbfs 初始化 邊 mmatrix new int vlen vlen for...