Firetruck
input
The city has a separate map for each fire district. Streetcorners of each map are identified by positive integers less than 21, with the firestation always on corner #1. The input file contains several test cases representing different fires in different districts.
• The first line of a test case consists of a single integer which is the number of the streetcorner
closest to the fire.
• The next several lines consist of pairs of positive integers separated by blanks which are the adjacent streetcorners of open streets. (For example, if the pair 4 7 is on a line in the file, then the street between streetcorners 4 and 7 is open. There are no other streetcorners between 4 and 7 on that section of the street.)
• The final line of each test case consists of a pair of 0’s.
output
For each test case, your output must identify the case by number (‘CASE 1:’, ‘CASE 2:’, etc). It must list each route on a separate line, with the streetcorners written in the order in which they appear on the route. And it must give the total number routes from firestation to the fire. Include only routes which do not pass through any streetcorner more than once. (For obvious reasons, the fire department doesn’t want its trucks driving around in circles.)
Output from separate cases must appear on separate lines.
Sample Input
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
Sample Output
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.
题意理解:
根据给出的节点通路到达指定位置
解题思路:
(大佬眼里的水题,我眼里的超难题(未来的路还很长啊(笑。)这道题用 DFS+回溯 会超时,是因为在整个查找的时候效率太低,所以要把走过的点单独拿出来,再去找走过的路径。
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
const int maxn = 21+4;
int m[maxn],e[maxn][maxn],mark[maxn],save[maxn]; //判断是否走过、邻接矩阵、会经过的所有节点、保存路径
int ans,ans1,n;
void Mark(int x){ //开始找所有会经过的点
mark[x] = 1;
for(int i=1; i<=maxn; i++){
if(m[i]==0 && mark[i]==0 && e[i][x]){ //该点没有被记录并且是通路
mark[i]==1;
Mark(i);
}
}
}
void dfs(int x,int ans){
if(x==n){
ans1++;
cout << '1';
for(int i=1; i<ans; i++) //输出路径
cout << ' ' << save[i];
cout << endl;
return;
}
for(int i=2; i<maxn; ++i){ //因为第一个一定会走 所以从第二个开始判断
if(e[x][i]==1&&m[i]==0&&mark[i]){ //节点是被访问过的且这条路是通路
save[ans] = i;
m[i] = 1;
dfs(i,ans+1); //递归
m[i] = 0;
}
}
}
int main(){
int cnt = 1;
while (cin >> n){
memset(e, 0, sizeof(e));
memset(save, 0, sizeof(save));
memset(mark,0,sizeof(mark));
int x = 1,y = 1;
ans1=0;
while(true){
cin >> x >> y;
if(x==0 || y==0)
break;
e[x][y] = e[y][x] = 1;
}
cout << "CASE " << cnt++ << ":" << endl;
Mark(n);
dfs(1,1);
cout <<"There are " << ans1 << " routes from the firestation to streetcorner " << n << "." <<endl;
}
}
本文章旨在记录学习,如有错误欢迎指正。