題目大意:
給出目標點和幾個邊,求從點1開始到目標點的所有可能路徑。
分析:
一開始就是簡單的回溯,提交發現TLE了。後來上網搜了搜,學到了一種新的剪枝方法。在回溯之前先用DFS進行判斷,判斷有哪些點可以到達目標點,將他們進行標記,然後在DFS中判斷這些點,這樣就可以大大提高效率。
#include<algorithm>
#include<cmath>
#include<cstring>
#include<string>
#include<cstdio>
#include<iostream>
using namespace std;
int a[30][30];
int vis[30];
int ans[30];
int liantong[30];
int target;
int sum;
int maxlu;
void init(int cur)
{
liantong[cur]=1;
for(int i=1;i<=maxlu;i++)
{
if(a[i][cur]&&!liantong[i])
init(i);
}
}
void dfs(int cur,int num)
{
if(cur==target)
{
sum++;
int fi=1;
for(int i=0; i<num; i++)
{
if(fi)
{
cout<<ans[i];
fi=0;
}
else
cout<<" "<<ans[i];
}
cout<<endl;
}
else
{
for(int i=2; i<=maxlu; i++)
{
if(!vis[i]&&a[cur][i]&&liantong[i])
{
ans[num]=i;
vis[i]=1;
dfs(i,num+1);
vis[i]=0;
}
}
}
}
int main()
{
int cixun=1;
while(scanf("%d",&target)!=EOF)
{
maxlu=0;
sum=0;
int aa,bb;
memset(vis,0,sizeof(vis));
memset(a,0,sizeof(a));
memset(liantong,0,sizeof(liantong));
while(scanf("%d%d",&aa,&bb)&&aa+bb!=0)
{
maxlu=max(aa,maxlu);
maxlu=max(bb,maxlu);
a[aa][bb]=1;
a[bb][aa]=1;
}
init(target); //寫成init(1)是TLE的
ans[0]=1;
printf("CASE %d:\n",cixun++);
dfs(1,1);
printf("There are %d routes from the firestation to streetcorner %d.\n",sum,target);
}
return 0;
}