zoukankan      html  css  js  c++  java
  • PTA 7-33 地下迷宫探索 (图的DFS)

    本题考点:

    • 图的DFS遍历

    7-33 地下迷宫探索 (30分)
    地道战是在抗日战争时期,在华北平原上抗日军民利用地道打击日本侵略者的作战方式。地道网是房连房、街连街、村连村的地下工事,如下图所示。
    我们在回顾前辈们艰苦卓绝的战争生活的同时,真心钦佩他们的聪明才智。在现在和平发展的年代,对多数人来说,探索地下通道或许只是一种娱乐或者益智的游戏。本实验案例以探索地下通道迷宫作为内容。

    假设有一个地下通道迷宫,它的通道都是直的,而通道所有交叉点(包括通道的端点)上都有一盏灯和一个开关。请问你如何从某个起点开始在迷宫中点亮所有的灯并回到起点?
    输入格式:
    输入第一行给出三个正整数,分别表示地下迷宫的节点数N(1<N≤1000,表示通道所有交叉点和端点)、边数M(≤3000,表示通道数)和探索起始节点编号S(节点从1到N编号)。随后的M行对应M条边(通道),每行给出一对正整数,分别是该条边直接连通的两个节点的编号。
    输出格式:
    若可以点亮所有节点的灯,则输出从S开始并以S结束的包含所有节点的序列,序列中相邻的节点一定有边(通道);否则虽然不能点亮所有节点的灯,但还是输出点亮部分灯的节点序列,最后输出0,此时表示迷宫不是连通图。
    由于深度优先遍历的节点序列是不唯一的,为了使得输出具有唯一的结果,我们约定以节点小编号优先的次序访问(点灯)。在点亮所有可以点亮的灯后,以原路返回的方式回到起点。

    本题是一个图的 DFS 问题,我们需要保存图,然后根据出发点来进行图的 DFS 遍历。

    在这个DFS过程中,我们需要从小大到达来进行遍历,在读取结点后进行排序,然后进行 DFS 排序即可。

    完整代码:

    #include <iostream>
    #include <vector>
    #include <algorithm>
    using namespace std;
    
    const int maxn = 1010;
    
    int n, m, s;
    int sum = 0; // 经过的结点数目
    vector<int> G[maxn];
    bool vis[maxn] = {false}; // 是否访问过了
    
    bool flag = false; // 调整格式
    void DFS(int s)
    {
       sum++;
       if (flag)
       { // 调整格式
           printf(" %d", s);
       }
       else
       {
           printf("%d", s);
           flag = true;
       }
       vis[s] = true;
       int v;
       bool hasVis;
       for (int i = 0; i < G[s].size(); i++)
       {
           v = G[s][i];
           hasVis = false;
           if (vis[v] == false)
           {
               hasVis = true;
               DFS(v);
           }
           if (hasVis) // 如果访问了这个结点的临界结点,那么一定会返回来访问他
               printf(" %d", s);
       }
    }
    
    int main()
    {
       scanf("%d%d%d", &n, &m, &s);
       int u, v;
       for (int i = 0; i < m; i++)
       {
           scanf("%d%d", &u, &v);
           G[u].push_back(v);
           G[v].push_back(u);
       }
       for (int i = 1; i <= n; i++)
       { // 对结点进行排序
           sort(G[i].begin(), G[i].end());
       }
       DFS(s);
       if (sum != n)
           printf(" 0");
    
       return 0;
    }
    
  • 相关阅读:
    PythonのTkinter基本原理
    使用 Word (VBA) 分割长图到多页
    如何使用 Shebang Line (Python 虚拟环境)
    将常用的 VBScript 脚本放到任务栏 (Pin VBScript to Taskbar)
    关于 VBScript 中的 CreateObject
    Windows Scripting Host (WSH) 是什么?
    Component Object Model (COM) 是什么?
    IOS 打开中文 html 文件,显示乱码的问题
    科技发展时间线(Technology Timeline)
    列置换密码
  • 原文地址:https://www.cnblogs.com/veeupup/p/12666132.html
Copyright © 2011-2022 走看看