7-33 地下迷宫探索 (30 分)(思路加详解)
一:題目
7-33 地下迷宮探索 (30 分)地道戰是在抗日戰爭時期,在華北平原上抗日軍民利用地道打擊日本侵略者的作戰方式。地道網是房連房、街連街、村連村的地下工事,如下圖所示。
我們在回顧前輩們艱苦卓絕的戰爭生活的同時,真心欽佩他們的聰明才智。在現在和平發展的年代,對多數人來說,探索地下通道或許只是一種娛樂或者益智的游戲。本實驗案例以探索地下通道迷宮作為內容。
假設有一個地下通道迷宮,它的通道都是直的,而通道所有交叉點(包括通道的端點)上都有一盞燈和一個開關。請問你如何從某個起點開始在迷宮中點亮所有的燈并回到起點?
輸入格式:
輸入第一行給出三個正整數,分別表示地下迷宮的節點數N(1<N≤1000,表示通道所有交叉點和端點)、邊數M(≤3000,表示通道數)和探索起始節點編號S(節點從1到N編號)。隨后的M行對應M條邊(通道),每行給出一對正整數,分別是該條邊直接連通的兩個節點的編號。
輸出格式:
若可以點亮所有節點的燈,則輸出從S開始并以S結束的包含所有節點的序列,序列中相鄰的節點一定有邊(通道);否則雖然不能點亮所有節點的燈,但還是輸出點亮部分燈的節點序列,最后輸出0,此時表示迷宮不是連通圖。
由于深度優先遍歷的節點序列是不唯一的,為了使得輸出具有唯一的結果,我們約定以節點小編號優先的次序訪問(點燈)。在點亮所有可以點亮的燈后,以原路返回的方式回到起點。
輸入樣例1:
6 8 1 1 2 2 3 3 4 4 5 5 6 6 4 3 6 1 5輸出樣例1:
1 2 3 4 5 6 5 4 3 2 1輸入樣例2:
6 6 6 1 2 1 3 2 3 5 4 6 5 6 4輸出樣例2:
6 4 5 4 6 0二 :思路
典型的DFS遍歷,但要深刻理解DFS遍歷的過程,也就是遞歸的過程,DFS中要牢記遍歷到最后一個結點程序還沒有結束,還需要返回去 去遍歷沒有訪問過的點,因為在DFS遍歷訪問鄰接點中,是按小序號來遍歷的。
三:對DFS和BFS遍歷不熟悉的可以學一下哈
DFS和BFS速遞
四:上碼
#include<bits/stdc++.h> using namespace std;typedef struct GNode* PtrGraph; typedef struct GNode{int Nv;int Ne;int Date[1001][1001]; }gnode;int visited[1001] = {0}; int cnt = 0; int N,M,K;//創建圖 void createGraph(PtrGraph G){cin >> N >> M >> K;G->Nv = N;G->Ne = M;//鄰接矩陣初始化for( int i = 1; i <= G->Nv; i++){for( int j = 1; j <= G->Nv; j++){G->Date[i][j] = 0; }} //往鄰接矩陣賦值for(int i = 1; i <= G->Ne; i++ ){int a,b;cin >> a >> b;G->Date[a][b] = 1;G->Date[b][a] = 1;} } //dfs遍歷 void DFS_Graph(PtrGraph G,int x){if (cnt == 0)cout << x;elsecout << ' ' <<x ;cnt++;visited[x] = 1;for(int i = 1; i <= G->Nv; i++ ){if( visited[i] != 1 && G->Date[x][i] == 1){DFS_Graph(G,i);cout << ' ' << x;}} } int main(){PtrGraph G = (PtrGraph)malloc(sizeof(struct GNode));createGraph(G);DFS_Graph(G,K);if( cnt != N)cout << ' ' << "0"; }五:不明白的碼
我寫的第一個碼是用到了容器可就是最后兩個點過不去,搞不懂 ,一個是直接輸出,而我的是將輸出結果存在容器中但就是過不去 ,大佬明白請留言
/**思路:DFS遍歷 然后用兩個容器進行儲存 一個是 vector用來儲存正確的順序一個是用棧來儲存,主要是用來反序輸出 但是棧頂的元素不要*/ #include<bits/stdc++.h> using namespace std;typedef struct GNode* PtrGraph; typedef struct GNode{int Nv;int Ne;int Date[1001][1001]; }gnode;int visited[1001] = {0}; vector<int>v,v2; stack<int>s; int N,M,K;//創建圖 void createGraph(PtrGraph G){cin >> N >> M >> K;G->Nv = N;G->Ne = M;//鄰接矩陣初始化for( int i = 1; i <= G->Nv; i++){for( int j = 1; j <= G->Nv; j++){G->Date[i][j] = 0; }} //往鄰接矩陣賦值for(int i = 1; i <= G->Ne; i++ ){int a,b;cin >> a >> b;G->Date[a][b] = 1;G->Date[b][a] = 1;} } int cnt = 0; //dfs遍歷 void DFS_Graph(PtrGraph G,int x){int temp = x;v.push_back(temp);cnt++;visited[x] = 1;for(int i = 1; i <= G->Nv; i++ ){if( visited[i] != 1 && G->Date[x][i] == 1){DFS_Graph(G,i);//將返回時路保存進去 v2.push_back(temp);}} } //輸出結果 void result(){for(int i = 0; i < v.size(); i++){cout << v[i] << ' '; }for(int i = 0; i < v2.size(); i++){if(i == v2.size() - 1)cout << v2[i];elsecout << v2[i] << ' '; } } int main(){PtrGraph G = (PtrGraph)malloc(sizeof(struct GNode));createGraph(G);DFS_Graph(G,K);if(v.size() == N ){result();}else{result();cout << ' ' << "0";} }六:總結
加油加油!
總結
以上是生活随笔為你收集整理的7-33 地下迷宫探索 (30 分)(思路加详解)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 奥特曼俱乐部怎么玩?
- 下一篇: java中的线程不安全和实例解析