原题链接:
比较麻烦,就不挂,可以上uva live找,也可以用virtual judge挂题。
题意:
输出从1到k的所有路径,不能重复经过
分析:
这题就是简单的深搜回溯,用一个数组记录路径,满足条件时输出。紫书上说需要先判断1到k是否联通,不然会超时。交了一发直接深搜,果然TLE。所以需要先判连通。
判连通的方法有(能想到的):
1、dfs和bfs,两者感觉差不多,但是我选择的bfs
2、floyd,n^3的复杂度,但更加粗暴直接,也更好写
3、待添加
感悟:
不预先判连通3000ms超时,判了连通就0ms秒AC,感慨啊。
代码:
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <vector> 5 #include <set> 6 #include <map> 7 #include <algorithm> 8 #include <string> 9 #include <queue> 10 #include <cmath> 11 #include <stack> 12 #include <cctype> 13 #include <list> 14 15 #define ll long long 16 #define ull unsigned long long 17 #define VNAME(name) (#name) 18 #define debug(a) cout<<VNAME(a)<<" = "<<(a)<<endl; 19 20 using namespace std; 21 22 const int maxn = 100010; 23 const int inf = 1 << 30; 24 int k; 25 vector<int> edge[22]; 26 queue<int> q; 27 bool vis[22]; 28 int road[22]; 29 int sum; 30 31 void init() { 32 memset(vis,0,sizeof(vis)); 33 for(int i=0; i<22; i++) { 34 edge[i].clear(); 35 } 36 sum=0; 37 } 38 39 //一个很标准的宽搜 40 bool bfs(int v) { 41 bool mark[22]= {0}; 42 while(!q.empty())q.pop(); 43 q.push(v); 44 mark[v]=1; 45 while(!q.empty()) { 46 int s=q.front(); 47 q.pop(); 48 if(s==k)return true;//找到k点,返回 49 for(int i=0; i<edge[s].size(); i++) { 50 if(!mark[edge[s][i]]) { 51 q.push(edge[s][i]); 52 mark[edge[s][i]]=1; 53 } 54 } 55 } 56 return false; 57 } 58 59 60 void dfs(int v,int cnt) { 61 road[cnt]=v;//记录路径 62 if(v==k) { 63 for(int i=0; i<cnt; i++) { 64 printf("%d ",road[i]); 65 } 66 printf("%d\n",road[cnt]); 67 sum++;//记录路径数量 68 return ; 69 } 70 for(int u=0; u<edge[v].size(); u++) { 71 if(!vis[edge[v][u]]) { 72 vis[v]=1;//标记原点 73 dfs(edge[v][u],cnt+1); 74 vis[v]=0;//回溯 75 } 76 } 77 } 78 79 int main() { 80 //iostream::sync_with_stdio(false); 81 82 #ifndef ONLINE_JUDGE 83 freopen("in.txt","r",stdin); 84 //freopen("out.txt","w",stdout); 85 #endif 86 87 int kace=0; 88 while(~scanf("%d",&k)) { 89 init();//预处理清空 90 int v,u; 91 while(scanf("%d%d",&v,&u)) { 92 if(v==0&&u==0)break; 93 edge[v].push_back(u); 94 edge[u].push_back(v);//无向图双向连边 95 } 96 for(int i=0; i<22; i++) { 97 sort(edge[i].begin(),edge[i].end());//排序,可以很方便的让dfs出来的路径按字典序排列 98 } 99 printf("CASE %d:\n",++kace); 100 if(bfs(1))dfs(1,0);//如果连通,开始深搜 101 printf("There are %d routes from the firestation to streetcorner %d.\n",sum,k); 102 } 103 return 0; 104 }
时间: 2024-10-14 17:36:03