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 回溯+剪枝 数据

猜你喜欢

转载自blog.csdn.net/jianglw1/article/details/83789332
今日推荐