UVA - 208 Firetruck
UVA - 208 Firetruck
题目大意
构造出一张图,给出一个点,让你按字典序输出所有从1到该点的路径
一开始直接DFS超时了
后面看到大佬的优化,大意就是很多起点与终点不相连,需要一开始剪枝舍去,具体操作就反着来,只要判断下起点和终点能不能相连就行了。
算法设计:
先从终点出发,无回溯的走遍和终点相连的所有点并标记为used,然后从起点出发,DFS判断下标记,这样就不会多走很多路了。
#include <stdio.h>
#include <iostream>
#include <cstdlib>
#include <cmath>
#include <cctype>
#include <string>
#include <cstring>
#include <algorithm>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <ctime>
#include <vector>
#include <fstream>
#include <list>
#include <iomanip>
#include <numeric>
using namespace std;
#define ll long long
#define ull unsigned long long
#define pi acos(-1)
const int inf = 0x3f3f3f3f;
const int N=25;
int n,cnt;
int matrix[N][N],rad[N];
bool vis[N*N];
bool used[N*N];
void check(int pos){//无回溯的走遍和终点相连的所有点并标记为used
used[pos]=true;
for(int i=2;i<N;i++){
if(matrix[i][pos]&&!used[i]){
check(i);
}
}
}
void dfs(int pos,int num){//遍历
if(pos==n){
cnt++;
printf("1");
for(int i=1;i<num;i++){
printf(" %d",rad[i]);
}
printf("\n");
return;
}
for(int i=2;i<N;i++){
if(matrix[pos][i]==1&&!vis[i]&&used[i]){
vis[i]=true;
rad[num]=i;
dfs(i,num+1);
vis[i]=false;
}
}
return;
}
int main()
{
int t=1;
while(~scanf("%d",&n)){
memset(matrix,0,sizeof(matrix));
memset(used,false,sizeof(used));
cnt=0;
int x,y;
while(1){
scanf("%d%d",&x,&y);
if(x==0||y==0){
break;
}
matrix[x][y]=matrix[y][x]=1;
}
printf("CASE %d:\n",t++);
check(n);
dfs(1,1);
printf("There are %d routes from the firestation to streetcorner %d.\n",cnt,n);
}
return 0;
}
最后贴一个我参考的博客
UVa 208 - Firetruck 回溯+剪枝 数据