資料結構與演算法題目集7-33——地下迷宮探索
阿新 • • 發佈:2018-12-08
我的資料結構與演算法題目集程式碼倉:https://github.com/617076674/Data-structure-and-algorithm-topic-set
原題連結:https://pintia.cn/problem-sets/15/problems/860
題目描述:
知識點:圖的深度優先遍歷
思路:圖的深度優先遍歷
一開始我的思路是先得到深度優先遍歷的結果,再逆序輸出該路徑即可,但是這樣做我就忽略了這樣一種情況:路徑中某節點在回退的過程中被多次訪問(測試點2)。因此,正確的做法是,在遞迴呼叫dfs函式訪問下一個節點之後,將當前節點加入路徑中。對於最後一個節點,其所有鄰接點均被訪問,也就不會將其再次加入路徑中,即不會重複輸出最後一個點。
給出本題各個測試點的測試資料:
序號 | 輸入 | 輸出 | 說明 |
0 | 6 8 1 1 2 2 3 3 4 4 5 5 6 6 4 3 6 1 5 |
1 2 3 4 5 6 5 4 3 2 1 | 一般有解的簡單情況 |
1 | 6 6 6 1 2 1 3 2 3 5 4 6 5 6 4 |
6 4 5 4 6 0 | 迷宮圖不連通 |
2 | 8 10 1 1 2 1 5 1 7 2 6 6 4 3 4 4 5 4 7 3 5 7 8 | 1 2 6 4 3 5 3 4 7 8 7 4 6 2 1 | 路徑中某節點被訪問多次 |
3 | 1000個節點,3000條通道的連通地下迷宮 | 略 | 邊界測試:最大N和M |
C++程式碼:
#include<iostream> #include<set> #include<vector> using namespace std; int N, M, S; set<int> graph[1001]; bool visited[1001]; vector<int> path; void dfs(int nowVisit); int main() { scanf("%d %d %d", &N, &M, &S); for(int i = 0; i < M; i++) { int v1, v2; scanf("%d %d", &v1, &v2); graph[v1].insert(v2); graph[v2].insert(v1); } fill(visited + 1, visited + N + 1, false); dfs(S); for(int i = 1; i <= N; i++){ if(!visited[i]){ path.push_back(0); break; } } for(int i = 0; i < path.size(); i++) { printf("%d", path[i]); if(i != path.size() - 1) { printf(" "); } else { printf("\n"); } } return 0; } void dfs(int nowVisit) { visited[nowVisit] = true; path.push_back(nowVisit); for(set<int>::iterator it = graph[nowVisit].begin(); it != graph[nowVisit].end(); it++) { if(!visited[*it]) { dfs(*it); path.push_back(nowVisit); } } }
C++解題報告: