(判连通+暴力)UVA - 208 Firetruck

原题链接:

比较麻烦,就不挂,可以上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

(判连通+暴力)UVA - 208 Firetruck的相关文章

UVa 208 Firetruck【回溯】

题意:给出一个n个节点的无向图,以及某个节点k,按照字典序从小到大输出从节点1到节点k的所有路径 看的题解 http://blog.csdn.net/hcbbt/article/details/9755147 因为节点数很少(小于20),所以可以先用floyd处理一下,判断一点是否能够到达终点 然后就像紫书里面枚举排列那样的去挨个找出字典序从小到大的路径 题解里面说到的无回溯的走遍和终点相连的所有点,他写的代码是判断的d[en][i],判断终点到i点是否可达 写成d[i][en]也能过,因为是无

UVA - 208 Firetruck(消防车)(并查集+回溯)

题意:输入着火点n,求结点1到结点n的所有路径,按字典序输出,要求结点不能重复经过. 分析:用并查集事先判断结点1是否可以到达结点k,否则会超时.dfs即可. #pragma comment(linker, "/STACK:102400000, 102400000") #include<cstdio> #include<cstring> #include<cstdlib> #include<cctype> #include<cmat

HDU 1317 XYZZY (SPFA 找正环 + Floyd 判连通)

XYZZY Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 3004    Accepted Submission(s): 817 Problem Description It has recently been discovered how to run open-source software on the Y-Crate gami

[无向图判连通]4.17平平凡凡才是真

因为下雨外加睡不醒所以这几天状态萎靡不振 决定开始刷题了,保持每天一道或者三天两道的进度吧 知识点随着刷题慢慢补吧 放弃爆炸oj了,蒟蒻的自我救赎 今天的题是[USACO16OPEN]关闭农场Closing the Farm 本蒟蒻的第一反应:强行spfa判连通 事实证明如果不是不知道哪里写错的玄学错误应该是能拿50分的 看了一下题解 思路大概是不考虑删点 从最后一个点开始加点判断连通与否 然后再倒着输出就好 要求:离线操作 具体实施:并查集 我和你连通,爸爸就一样 一旦出现两个或两个以上爸爸,

上海市高校大学生程序设计邀请赛 C:小花梨判连通

Problem C.小花梨判连通 时间限制:2000ms 空间限制:512MB Description 小花梨给出??个点,让??位同学对这??个点任意添加无向边,构成??张图.小花梨想知道对于 每个点??,存在多少个点??(包括??本身),使得??和??在这??张图中都是连通的. Input 第一行输入两个正整数??和??,分别表示点的个数和同学数. 接下来分成??部分进行输入,每部分输入格式相同. 每部分第一行输入一个整数????,表示第??位同学连边的数目. 接下来????行,每行两个正整

【UVa】208 Firetruck(dfs)

题目 题目 ? ? 分析 一开始不信lrj的话,没判联通,果然T了. 没必要全部跑一遍判,只需要判断一下有没有点与n联通,邻接表不太好判,但无向图可以转换成去判n与什么联通. 关于为什么要判,还是因为数据造的强,造了许多之前的节点情况巨多,然而所有节点都不和中点连接的情况...... ? ? 代码 #include <bits/stdc++.h> using namespace std; int n; vector<int> G[100]; vector<int> An

Firetruck UVA - 208

DFS+并查集 如果只用DFS的话会超时,用并查集剪枝,和起点终点不联通的点就不用跑了 这题有好多人写了博客,但是我觉得我的代码写的比较通俗易懂所以就贴上来了,我觉得我写代码的目标就是让任何人都能看懂,越小白越好(其实是因为真小白吧-- #include<bits/stdc++.h> using namespace std; int E[30][30]; int diste; int mark[30]; int path[30]; int fin[30]; int ans; int root[

【UVa 208】Firetruck

The Center City ?re department collaborates with the transportation department to maintain mapsof the city which re?ects the current status of the city streets. On any given day, several streets areclosed for repairs or construction. Fire?ghters need

UVa 208 消防车(dfs+剪枝)

https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=144 题意:给出一个n个结点的无向图以及某个结点k,按照字典序从小到大顺序输出从1到结点k的所有路径. 思路:如果直接矩阵深搜的话是会超时的,所以我们可以从终点出发,将与终点相连的连通块保存起来,这样dfs深搜时可以剪枝掉一些到达不了的点.只要解决了这个,dfs就是小问题. 这道题还有点坑的