本题可以直接提前判断是否能到达目标地点进行剪枝,还有需要注意的地方就是输出格式了。
//#include<bits/stdc++.h>//poj,hdu can't use it
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <stack>
#include <map>
#include <cmath>
#include <algorithm>
#include <iomanip>
using namespace std;
/************************head file************************/
#define inf 0x3f3f3f3f
#define SI(x) scanf("%d",&x)
#define set0(x) memset(x,0,sizeof(x))
#define ms(x,n) memset(x,n,sizeof(x));
typedef long long ll;
const int mod = 998244353;
const int maxn = 22;
using namespace std;
/***********************defination************************/
int n,step,route;
int m[maxn][maxn];//记录连通
int path[maxn];//记录路径
int vis[maxn];
int trunk[maxn];//记录是否能到达
void init(int cur) //从终点开始遍历,保存与终点相连的连通块
{
trunk[cur] = 1;
for (int i = 1; i < maxn; i++)
{
if (m[cur][i] && !trunk[i])
init(i);
}
}
void dfs(int cur,int step)
{
if(cur == n)
{
cout << "1";
for (int i = 1; i < step; i++)
cout<<" "<< path[i];
cout<<endl;
route++;
}
for (int i = 0; i < maxn; i++)
{
if (m[cur][i]&&!vis[i])
{
vis[i] = 1;
path[step] = i;
dfs(i, step + 1);
vis[i] = 0;
}
}
return;
}
int main()
{
int a,b,kase = 0;
while(cin>>n&&n)
{
set0(vis);
set0(m);
set0(path);
set0(trunk);
while (cin>>a>>b&&a&&b)
{
m[a][b] = m[b][a] = 1;
}
vis[1] = 1;
step = 1;
route = 0; //记录路径数量
init(n); //计算保存连通块
if(trunk[1] == 0)//剪枝
{
cout <<"CASE "<<++kase<<":"<<endl;
cout <<"There are "<<0<<" routes from the firestation to streetcorner "<<n<<"."<<endl;
continue;
}
else{
cout<<"CASE "<<++kase<<":"<<endl;
dfs(1,1);
cout <<"There are "<<route<<" routes from the firestation to streetcorner "<<n<<"."<<endl;
}
}
return 0;
}