地下迷宫探索

问题描述:
地道战是在抗日战争时期,在华北平原上抗日军民利用地道打击日本侵略者的作战方式。地道网是房连房、街连街、村连村的地下工事,如下图所示。
我们在回顾前辈们艰苦卓绝的战争生活的同时,真心钦佩他们的聪明才智。在现在和平发展的年代,对多数人来说,探索地下通道或许只是一种娱乐或者益智的游戏。本实验案例以探索地下通道迷宫作为内容。
假设有一个地下通道迷宫,它的通道都是直的,而通道所有交叉点(包括通道的端点)上都有一盏灯和一个开关。请问你如何从某个起点开始在迷宫中点亮所有的灯并回到起点?

输入格式:
输入第一行给出三个正整数,分别表示地下迷宫的节点数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就是随机选定一个起点将其标记为已经访问过的点,然后就是递归调用进行与其相邻的点的搜索,直到所有的点都被访问完。

存储方式:
这里使用结构体,方便递归传递,当然也可全局定义二维数组建图已经点边数据。
实际上的代码dnf只使用了1个标记数组,从起点开始,起点满足未访问,输出,并且标记Visited[i],然后每次从邻接结点小的开始搜索,满足条件,调用dnf进行递归,直到找不到未访问点,原路返回上一dnf调用,输出该结点,不必保存,直到能访问的点都访问完毕,结束dnf调用。

代码思路:
建立图->遍历访问点->标记访问点->输出返回点->遍历标记数组判断是否有未访问点->结束

AC代码:

#include<iostream>
#include<memory.h>
using namespace std;
struct Graph{
    int a[1001][1001];
    int Node;
    int Route;
};
int StartPoint;
Graph *CreatMap(){
    Graph *g = new Graph;
    memset(g->a,0,sizeof(g->a));
    cin >>g->Node>>g->Route>>StartPoint;//输入点、边、起点
    int x,y;
    for(int i = 0;i < g->Route;i++){//循环输入各边信息
        cin >> x >> y;
        g->a[x][y] = g->a[y][x] = 1;
    }
    return g;
}
void dfs(Graph *g,int i,int Visited[]){
    if(i == StartPoint)
        cout << i;
    else
        cout << " " << i;
    Visited[i] = 1;
    for(int j = 1;j <= g->Node;j++){
        if(Visited[j] == 0 && g->a[i][j] == 1){
            dfs(g,j,Visited);
            cout <<" " << i; //返回
        }
    }
}
int main(){
    Graph *g = CreatMap();//建立联通图
    int Visited[1001] = {0}; //记录访问过的节点
    dfs(g,StartPoint,Visited);
    for(int i = 1;i <= g->Node;i++){
        if(Visited[i] == 0){
            cout << " 0";
            break;
        }
    }
    return 0;
}
上一篇:1631. 最小体力消耗路径


下一篇:Python中的变量引用对象需注意的几点