這個題,就是用回溯解,但是要先優化一下,用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;
}