题目描述

中心城市消防部门与运输部门合作,维护反映城市街道现状的城市地图。消防员需要能够选择从火警站到火警的路线。
中心城市分为不重叠的消防区。当报告发生火灾时,中央调度员通知火灾发生地区最近的火警站,并列出可能路线。您必须编写一个程序,中央调度员可以使用该程序来生成从地区火警站到火灾的路线。

输入

消防区都用小于 21 的正整数来标识,而且火场始终位于第一个消防区。输入文件包含多个测试用例,代表不同火灾。
• 测试用例的第一行由一个整数组成,该整数是距离火灾最近的火警站。
• 接下来的几行由成对的正整数组成,这些成对的正整数是开放街道相邻的消防区。(例如,如果对 4 7 在一行上,则消防区 4 和消防区 7 之间的街道是开放的。没有其他消防区在 4 和 7 之间。)
• 每个测试用例的最后一行由一对 0 组成。

输出

对于每个测试用例,您的输出必须通过编号来标识用例(”CASE 1:”,”CASE 2:”等)。它必须列出每条路线,并按照字典序从小到大输出。它必须提供从火警站到火灾地点的总路线。
不同用例的输出必须分开显示。

样例输入

6
1 2
1 3
3 4
3 5
4 6
5 6
2 3
2 4
0 0
4
2 3
3 4
5 1
1 6
7 8
8 9
2 5
5 7
3 1
1 8
4 6
6 9
0 0

样例输出

CASE 1:
1 2 3 4 6
1 2 3 5 6
1 2 4 3 5 6
1 2 4 6
1 3 2 4 6
1 3 4 6
1 3 5 6
There are 7 routes from the firestation to streetcorner 6.
CASE 2:
1 3 2 5 7 8 9 6 4
1 3 4
1 5 2 3 4
1 5 7 8 9 6 4
1 6 4
1 6 9 8 7 5 2 3 4
1 8 7 5 2 3 4
1 8 9 6 4
There are 8 routes from the firestation to streetcorner 4.

分析

  • 这道题主要就是要我们按照所给的地图,找到并按字典序输出火警到火灾地点的所有路径。
  • 这道题和以往不同的的是,并不是直接给出矩阵地图,而是通过给出点的连接情况来给出地图。这很容易让入门新手无从下手,但是如果你学过数据结构或者离散数学的话,你会知道我们可以把给出的图用矩阵表示。

    • 首先,我们要以比题目给的最大地点号(本题是21)稍大的值,来创建一个二维数组map[maxn][maxn]。
    • 然后,根据输入的连通情况,在矩阵上做标记。本题给的是个无向图,比如:输入了一个2 6,表示2和6之间连通,就在矩阵二行六列和六行二列的地方标记1(true)。
    • 题目给出样例一表示的矩阵为:
      0 1 1 0 0 0
      1 0 1 1 0 0
      1 1 0 1 1 0
      0 1 1 0 0 1
      0 0 1 0 0 1
      0 0 0 1 1 0(注意:已经忽略0行0列)
  • 有了矩阵地图,这道题又可以像以前用搜索解决了。考虑到按字典序输出,我们用深度优先搜索比较恰当。
  • 这道题的样例输入比较麻烦,win7的控制台不能复制粘贴,如果我们要多次调试,输入数据会很烦。这里可以用一个,我刚刚学到的小技巧:

    • 首先,在.cpp所在的文件夹中创建一个test.txt文件,接着把要输入的数据黏贴到该.txt文件中。
    • 然后在main()函数中加入freopen(“test.txt”,”r”,stdin),即可实现文件输入。(该函数包含在cstdio头文件中)

代码如下

#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
const int maxn=21+4;
int map[maxn][maxn]={0};//用来存储地图
int mark[maxn];//用来记录走过的点,以便输出
bool m[maxn];//用来记忆该点有没有被访问过
int n,ans1;//ans1记录总共有多少条路径
void dfs(int x,int ans)//x表示所在的地点,ans表示这是去到的第几个地点
{if(x==n){ans1++;cout<<'1';for(int i=1;i<ans;i++)cout<<' '<<mark[i];cout<<endl;return ;}for(int i=2;i<maxn;i++)//从2开始逐个搜索,因为是从1出发,不能再回到1if(map[x][i]==1&&!m[i])//如果i点与x点连通,而且i点没被访问过{mark[ans]=i;m[i]=true;dfs(i,ans+1);m[i]=false;}return ;
}
int main()
{//freopen("text.txt","r",stdin);//文件输入int cnt=1;while(cin>>n){memset(map,0,sizeof(map));//一轮下来,有些数据要被重置int x=1,y=1;ans1=0;//重置while(true){cin>>x>>y;if(x==0||y==0)break;map[x][y]=map[y][x]=1;//构建矩阵地图}cout<<"CASE "<<cnt++<<":"<<endl;dfs(1,1);cout<<"There are "<<ans1<<" routes from the firestation to streetcorner "<<n<<"."<<endl;}return 0;
}

优化

  • 用回溯法预先找到能到达的路径,记录在bool fir[maxn]数组中。如果fir[i]=true,则说明该点能到达终点。
    //似乎优化后跑得更慢了
void check(int x)
{fir[x]=true;for(int i=2;i<maxn;i++)if(map[x][i]&&!fir[i])check(i);
}
//还要每次用memset(fir,false,sizeof(fir));重置
//在dfs前调用check()函数

Firetruck(DFS+回溯)相关推荐

  1. HDU1016 Prime Ring Problem dfs+回溯

    点击打开链接 Prime Ring Problem Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Jav ...

  2. LeetCode 980. 不同路径 III(DFS+回溯)

    1. 题目 在二维网格 grid 上,有 4 种类型的方格: 1 表示起始方格.且只有一个起始方格. 2 表示结束方格,且只有一个结束方格. 0 表示我们可以走过的空方格. -1 表示我们无法跨越的障 ...

  3. [DFS|回溯法] leetcode 17 电话号码的字母组合

    [DFS|回溯法] leetcode 17 电话号码的字母组合 1.题目 题目链接 给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合. 给出数字到字母的映射如下(与电话按键相同).注意 ...

  4. PAT1087 All Roads Lead to Rome (30)(最短路径+dfs+回溯)

    题意: 有N个城市,M条无向边,从某个给定的起始城市出发,前往名为ROM的城市.每个城市(除了起始城市)都有一个点权(称为幸福值),和边权(每条边所需的花费).求从起点到ROM所需要的最少花费,并输出 ...

  5. 洛谷 P1219-八皇后(dfs回溯)

    题目描述 网址传送:https://www.luogu.com.cn/problem/P1219 八皇后问题描述:介是一个古老而著名的问题,是回溯算法的典型案例.该问题是国际西洋棋棋手马克斯·贝瑟尔于 ...

  6. 【DFS+回溯+字符串】【洛谷P1019】【单词接龙】

    传送门 /*[DFS+回溯+字符串][洛谷P1019][单词接龙]https://www.luogu.com.cn/problem/P1019题意:给你很多个单词 一个开头首字母 每个单词至多用2次 ...

  7. DFS+回溯算法专题

    基础知识 回溯法是一种选优搜索法(试探法),被称为通用的解题方法,这种方法适用于解一些组合数相当大的问题.通过剪枝(约束+限界)可以大幅减少解决问题的计算量(搜索量). 深度优先搜索(Depth-Fi ...

  8. [洛谷]P1706 全排列问题(简单dfs+回溯)

    dfs+回溯: Acode: #include<bits/stdc++.h> using namespace std; #define int long long int n,a[10]; ...

  9. Leetcode一起攻克搜索(BFS,DFS,回溯,并查集)

    文章目录 BFS简介 DFS简介 回溯简介 并查集简介 DFS题目 690. 员工的重要性 1.dfs解法: 2.bfs算法 547.朋友圈 dfs解法 200.岛屿数量 dfs解法 417.太平洋大 ...

最新文章

  1. util.sh 脚本
  2. Realm数据库存储 使用详解
  3. eclipse 配置jsp
  4. Codeforces Round #734 (Div. 3) 题解
  5. android安全 报告,Android安全检测报告
  6. linux新建脚本文件,linux shell脚本编程2—修改文件时间和创建新文件即touch命令的使用...
  7. 企业如何开展数据可视化建设
  8. C#写的34401A串口232数据读取程序
  9. [leetcode]5354. 通知所有员工所需的时间
  10. 利用遗传算法求解TSP问题
  11. PHP字符串作为字节数组,哈希hash然后base64编码
  12. linux上安装安卓厨房手机版,【图片】【教程】进阶教程之“使用安卓厨房制作/修改ROM包”【联想a798t吧】_百度贴吧...
  13. CAXA 数控车编程视频教程 CAXA车床绘图教程
  14. acc转mp3最好用的格式转换器推荐?
  15. 华为路由器配置OSPF实现不同网段通信
  16. 天翼网关设置-路由器
  17. 基于STM32F429,Cubemx的SDHC卡的基本Fatfs文件移植
  18. 360度领导能力全方位测试
  19. 大白菜安装linux系统安装教程
  20. 无极电影的php,php无极

热门文章

  1. VTS工具测试指定的testcase函数(以VtsHalKeymasterV4_0TargetTest为例)
  2. 动态链接库编写与使用(VC6)
  3. Python对象注意点
  4. 想要求职Web安全相关的岗位,你就必须要懂的知识
  5. HttpURLConnection 发送post请求。并将结果以JSONObject对象返回的轮子
  6. MySQL查看表中的约束
  7. 4.2.3 减少磁盘延迟时间的方法
  8. 项目: 用easyx实现消砖块
  9. Linux之Sed详解
  10. ConcurrentMap接口