题意:构造出一张图,给出一个点,字典序输出所有从1到该点的路径
思路:这道题裸搜的话会超时,所以要进行必要的剪枝,刚开始我时用一个dfs从目标点开始搜,dfs能到达的点说明通过这个带你可以到达目标点,这样会超时,所以需要换另一种方法,这里我用的是flody,也可以用并查集。
代码:
#include <map> #include <set> #include <cmath> #include <queue> #include <stack> #include <cstdio> #include <vector> #include <iomanip> #include <cstdlib> #include <cstring> #include <iostream> #include <algorithm> #define ll long long #define mod 1000000007 #define mem(a) memset(a,0,sizeof(a)) using namespace std; const int maxn = 20 + 5, inf = 0x3f3f3f3f; bool vis[maxn]; int floyd[maxn][maxn]; int d[maxn]; bool G[maxn][maxn]; int n,cnt,Maxn,len; void print(){ cnt++; cout<<1; for(int i = 1 ; i < len ; i ++ ){ cout<<" "<<d[i]; } cout<<endl; } void dfs(int cur,int dd){ if(cur==n){ len = dd; print(); return; } else{ for(int i = 1 ; i <= Maxn ; i ++ ){ if(!vis[i]&&G[cur][i]&&floyd[n][i] != maxn){ d[dd] = i; vis[i] = true; dfs(i,dd+1); vis[i] = false; } } } } int main(){ // freopen("in.txt","r",stdin); // freopen("out.txt","w",stdout); int kase = 1 ; while(scanf("%d",&n)!=EOF){ memset(G,false,sizeof(G)); memset(vis,false,sizeof(vis)); for(int i = 1 ; i <= 21 ; i ++ ) for(int j = 1 ; j <= 21 ; j ++ ) floyd[i][j] = maxn; Maxn = 0; cnt = 0; printf("CASE %d:\n",kase++); int a,b; while(scanf("%d %d",&a,&b)!=EOF&&(a||b)){ G[a][b] = G[b][a] = true; floyd[a][b] = floyd[b][a] = 1; if(Maxn < a ) Maxn = a; if(Maxn < b ) Maxn = b; } for (int k = 1; k <= Maxn ; k ++ ) for (int i = 1; i <= Maxn ; i ++ ) for (int j = 1; j <= Maxn ; j ++ ) if (floyd[i][k] + floyd[k][j] < floyd[i][j]) floyd[i][j] = floyd[i][k] + floyd[k][j]; vis[1] = true ; dfs(1,1); printf("There are %d routes from the firestation to streetcorner %d.\n",cnt,n); } }