越做题目越上瘾。
最近在做搜索和DP,这个题目看就是直接深搜+回溯就行了。
写完直接TLE了,因为没有剪枝,总共有21个节点,还是太大了,一般都在8个节点左右的话貌似不剪枝都能过。
原来先要预处理一下,只考虑和目标站在一个连通块的点就行了。也就是求一个点的连通块。
写完了AC0.004s。果然剪枝不剪枝的终于见识到巨大威力了。
#include<stdio.h>
#include<string.h>
#define MAX 22
int maps[MAX][MAX];
int visited[MAX];
int path[MAX],truck[MAX];
int pointer;
int goal,routes;
void init(int cur){
int i;
truck[cur]=1;
for(i=1;i<MAX;i++){
if(maps[cur][i]&&!truck[i])
init(i);
}
}
void dfs(int n){
int i;
if(n==goal){
routes++;
printf("1");
for(i=1;i<pointer;i++)
printf(" %d",path[i]);
printf("\n");
}
else{
for(i=1;i<MAX;i++){
if(maps[n][i]&&!visited[i]&&truck[i]){
path[pointer++]=i;
visited[i]=1;
dfs(i);
visited[i]=0;
pointer--;
}
}
}
}
int main()
{
int a,b,case_num=1;
while(scanf("%d",&goal)!=EOF){
routes=0;
pointer=0;
memset(truck,0,sizeof(truck));
memset(maps,0,sizeof(maps));
memset(visited,0,sizeof(visited));
while(1){
scanf("%d%d",&a,&b);
if(!a&&!b)
break;
else
maps[a][b]=maps[b][a]=1;
}
printf("CASE %d:\n",case_num);
case_num++;
path[pointer++]=1;
visited[1]=1;
init(goal);
dfs(1);
printf("There are %d routes from the firestation to streetcorner %d.\n",routes,goal);
}
return 0;
}