题目大意:
给出目标点和几个边,求从点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;
}