(判连通+暴力)UVA

原题链接:

比较麻烦,就不挂,可以上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
",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:
",++kace);
100         if(bfs(1))dfs(1,0);//如果连通,开始深搜
101         printf("There are %d routes from the firestation to streetcorner %d.
",sum,k);
102     }
103     return 0;
104 }
原文地址:https://www.cnblogs.com/tak-fate/p/5773826.html