版权声明:我的GitHub:https://github.com/617076674。真诚求星! https://blog.csdn.net/qq_41231926/article/details/84892558
我的数据结构与算法题目集代码仓: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++解题报告: