1. 程式人生 > >資料結構與演算法題目集7-33——地下迷宮探索

資料結構與演算法題目集7-33——地下迷宮探索

我的資料結構與演算法題目集程式碼倉: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++解題報告: