• (判连通+暴力)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 }
  • 相关阅读:
    [php代码]从svn获取指定版本,并同步到ftp上。
    java程序用pid重启
    Gearman安装,测试笔记
    ant编译android项目
    jquery代码收藏
    [读书笔记]读《code complete》有感
    无法解析的外部符号_main,该符号在函数_tmainCRTStartup中被引用
    4路电梯调度——pair program总结
    阅读作业2
    必应缤纷桌面的使用测试
  • 原文地址:https://www.cnblogs.com/tak-fate/p/5773826.html
Copyright © 2020-2023  润新知