这个题,就是用回溯解,但是要先优化一下,用bfs从终点历遍到点1,并把这个路径上的边标记,在后面的dfs中只选择被标记过的边走,并且当点1的路径中没有一条被标记时,就不用dfs了。这样优化一下就不会TL了。
还有一点就是一定要看清题目格式要求,不然就会很难受了。蠢到爆炸的我输出语句的一个点没写上去,还吃了两发WA,难受。
代码如下:
#include<bits/stdc++.h>
using namespace std;
int have[22][22],vis[22],mark[22][22],que[22];
int n,sum;
bool is_mark(){
int h[22][22];
memcpy(h,have,sizeof(h));
queue<int> q;
q.push(n);
while(!q.empty()){
int g=q.front();q.pop();
for(int i=1;i<22;i++){
if(h[g][i]||h[i][g]){
mark[g][i]=mark[i][g]=1;
q.push(i);
h[g][i]=h[i][g]=0;
}
}
}
for(int i=2;i<22;i++)
if(mark[1][i]) return 1;
return 0;
}
void dfs(int d,int v){
if(v==n){
printf("1");
for(int i=1;i<d;i++) printf(" %d",que[i]);
printf("\n");
sum++;
return;
}
for(int u=2;u<22;u++){
if(!vis[u]&&have[v][u]&&mark[v][u]){
vis[u]=1;
have[v][u]=0;
que[d]=u;
dfs(d+1,u);
vis[u]=0;
have[v][u]=1;
}
}
}
int main(){
int a,b,all=0;
while(scanf("%d",&n)!=EOF){
memset(have,0,sizeof(have));
memset(vis,0,sizeof(vis));
memset(mark,0,sizeof(mark));
while(scanf("%d%d",&a,&b)&&a) have[a][b]=have[b][a]=1;
sum=0;
printf("CASE %d:\n",++all);
if(is_mark()) dfs(1,1);
printf("There are %d routes from the firestation to streetcorner %d.\n",sum,n);
}
return 0;
}