题目:

7-1 列出连通集 (30 分)

给定一个有N个顶点和E条边的无向图,请用DFS和BFS分别列出其所有的连通集。假设顶点从0到N−1编号。进行搜索时,假设我们总是从编号最小的顶点出发,按编号递增的顺序访问邻接点。

输入格式:

输入第1行给出2个整数N(0<N≤10)和E,分别是图的顶点数和边数。随后E行,每行给出一条边的两个端点。每行中的数字之间用1空格分隔。

输出格式:

按照 “ { v1, v2, v3, ... ,vk } ”的格式,每行输出一个连通集。先输出DFS的结果,再输出BFS的结果。

​1​​ v​2​​ ... v​k​​ }"的格式,每行输出一个连通集。先输出DFS的结果,再输出BFS的结果。

输入样例:

8 6
0 7
0 1
2 0
4 1
2 4
3 5

输出样例:

{ 0 1 4 2 7 }
{ 3 5 }
{ 6 }
{ 0 1 2 7 4 }
{ 3 5 }
{ 6 }

分析:

当读完这道题之后,很容易就能够知道我们需要做的两件事:①构建图  ②DFS遍历和BFS遍历

这里为了方便起见(同时数据量并不大),这里将采用邻接矩阵存储图。


代码:

对结构体结构的定义:

#define max 10
typedef int vertex_type;
typedef int edge_type;
typedef struct graph_matrix{
int n, e;//顶点数;边数
vertex_type vexs[max];//顶点一维数组
edge_type edges[max][max];//邻接矩阵二维数组,元素类型为vector<vertex_type>
}gm;

全局变量visit[]

//visit[]数组;全局变量
int visit[max] = {};

①构建图

//创建图
void create_gm(gm &gm)
{
cin>>gm.n>>gm.e;
memset(gm.edges, , sizeof(gm.edges));
for(int i=; i<gm.n; i++){
gm.vexs[i] = i;
} //输入边数据
int a, b;
for(int i=; i<gm.e; i++){
cin>>a>>b;
gm.edges[a][b] = ;
gm.edges[b][a] = ;
}
}

②DFS遍历

//深度优先
//id: 以id为起始点
void DFS(gm &gm, int id)
{
visit[id] = ;
cout<<id<<" ";
for(int i=; i<gm.n; i++){
if(gm.edges[i][id] == && visit[i] == ){
DFS(gm, i);
}
}
}

③BFS遍历

//宽度优先
void BFS(gm &gm, int id)
{
visit[id] = ;
queue<int> qu;
qu.push(id);
while(qu.size() != ){
int mark = qu.front();
qu.pop();
cout<<mark<<" ";
for(int i=; i<gm.n; i++){
if(gm.edges[i][mark] == && visit[i] == ){
visit[i] = ;
qu.push(i);
}
}
}
}

全部的代码:

#include<iostream>
#include<cstring>
#include<queue>
using namespace std; #define max 10
typedef int vertex_type;
typedef int edge_type;
typedef struct graph_matrix{
int n, e;//顶点数;边数
vertex_type vexs[max];//顶点一维数组
edge_type edges[max][max];//邻接矩阵二维数组,元素类型为vector<vertex_type>
}gm; //函数声明
void create_gm(gm &gm);
void DFS(gm &gm, int id);
void BFS(gm &gm, int id); //visit[]数组;全局变量
int visit[max] = {}; int main()
{
gm gm;//定义一个叫做gm的邻接矩阵
create_gm(gm); //调用DFS遍历
for(int i=; i<gm.n; i++){
if(visit[i] == )continue;
cout<<"{ ";
DFS(gm ,i);
cout<<"}"<<endl;
} //重置visit[]数组
memset(visit, , sizeof(visit)); //调用BFS遍历
for(int i=; i<gm.n; i++){
if(visit[i] == ){
cout<<"{ ";
BFS(gm ,i);
cout<<"}"<<endl;
}
}
return ;
} //创建图
void create_gm(gm &gm)
{
cin>>gm.n>>gm.e;
memset(gm.edges, , sizeof(gm.edges));
for(int i=; i<gm.n; i++){
gm.vexs[i] = i;
} //输入边数据
int a, b;
for(int i=; i<gm.e; i++){
cin>>a>>b;
gm.edges[a][b] = ;
gm.edges[b][a] = ;
}
} //深度优先
void DFS(gm &gm, int id)
{
visit[id] = ;
cout<<id<<" ";
for(int i=; i<gm.n; i++){
if(gm.edges[i][id] == && visit[i] == ){
DFS(gm, i);
}
}
} //宽度优先
void BFS(gm &gm, int id)
{
visit[id] = ;
queue<int> qu;
qu.push(id);
while(qu.size() != ){
int mark = qu.front();
qu.pop();
cout<<mark<<" ";
for(int i=; i<gm.n; i++){
if(gm.edges[i][mark] == && visit[i] == ){
visit[i] = ;
qu.push(i);
}
}
}
}

ALL


总结:

在这个题目中主要是对之前在树章节中,对关于树的前序遍历(DFS)和层次遍历(BFS)的知识迁移。

① DFS往往会运用到来进行实现,而递归就是利用栈的一个实现方法,递归特性使算法代码简洁的同时,也使算法理解困难,

所以对于我这种初学者来说画图和动手实践是最好的学习方法。

例子:“走迷宫,你没有办法用分身术同时走进多叉道路中,不撞南墙不回头。”(来源自网络)

② BFS则是要运用到队列,程序流程相对于DFS来说更为清晰。

例子:“当你眼镜掉了,你趴在地上找,你总是会先摸靠近你的地方,如果没有,再摸远一点的地方。”(来源自网络)

如何对已有知识的新运用也是能力提升的一种,在此我也对DFS和BFS有了更深一层的理解。

嘻嘻:)

列出连通集(DFS及BFS遍历图) -- 数据结构的更多相关文章

  1. 图的DFS与BFS遍历

    一.图的基本概念 1.邻接点:对于无向图无v1 与v2之间有一条弧,则称v1与v2互为邻接点:对于有向图而言<v1,v2>代表有一条从v1到v2的弧,则称v2为v1的邻接点. 2.度:就是 ...

  2. 邻接矩阵实现图的存储,DFS,BFS遍历

    图的遍历一般由两者方式:深度优先搜索(DFS),广度优先搜索(BFS),深度优先就是先访问完最深层次的数据元素,而BFS其实就是层次遍历,每一层每一层的遍历. 1.深度优先搜索(DFS) 我一贯习惯有 ...

  3. 数据结构上机实验dfs&&bfs遍历图

    #include<stdio.h> #include<string.h> #include<stdlib.h> #include<queue> #inc ...

  4. DFS和BFS遍历的问题

    来自https://github.com/soulmachine/leetcode 广度优先搜索 输入数据:没有什么特征,不像dfs需要有递归的性质.如果是树/图,概率更大. 状态转换图:数或者DAG ...

  5. 判断图连通的三种方法——dfs,bfs,并查集

    Description 如果无向图G每对顶点v和w都有从v到w的路径,那么称无向图G是连通的.现在给定一张无向图,判断它是否是连通的. Input 第一行有2个整数n和m(0 < n,m < ...

  6. 图的bfs遍历模板(邻接矩阵存储和邻接表存储)

    bfs遍历图模板伪代码: bfs(u){ //遍历u所在的连通块 queue q; //将u入队 inq[u] = true; while (q非空){ //取出q的队首元素u进行访问 for (从u ...

  7. 数据结构(三十二)图的遍历(DFS、BFS)

    图的遍历和树的遍历类似.图的遍历是指从图中的某个顶点出发,对图中的所有顶点访问且仅访问一次的过程.通常有两种遍历次序方案:深度优先遍历和广度优先遍历. 一.深度优先遍历 深度优先遍历(Depth_Fi ...

  8. [数据结构]图的DFS和BFS的两种实现方式

    深度优先搜索 深度优先搜索,我们以无向图为例. 图的深度优先搜索(Depth First Search),和树的先序遍历比较类似. 它的思想:假设初始状态是图中所有顶点均未被访问,则从某个顶点v出发, ...

  9. PTA 2-1 列出连通集【DFS+BFS基础】

    给定一个有N个顶点和E条边的无向图,请用DFS和BFS分别列出其所有的连通集.假设顶点从0到N−1编号.进行搜索时,假设我们总是从编号最小的顶点出发,按编号递增的顺序访问邻接点. 输入格式: 输入第1 ...

随机推荐

  1. Eclipse中文件结构的树形显示问题

    问题描述:在Eclipse中的SpringBoot文件显示层级消失. 这种情况下编辑代码的效率大大下降. 原因:Eclipse的工作模式不正确.上面的工作模式是Java模式.实际上应采用JavaEE模 ...

  2. HGOI 20190709 题解

    Problem A 紫色激情 一个序列$\{a_n\}$,求出方差最大的子序列. 其中方差 [l,r] 的定义是$S^2 = \frac{1}{n} \sum\limits_{i=l}^{r} (x_ ...

  3. source和resource的区别

    idea中,有时新导入的工程会出现 类的标识为红色的J,此时为无效,并且该类不能被编译,这是因为该类所在的文件夹java没有被标记为Sources Root,而放置配置文件的resources文件夹没 ...

  4. ORA-01652: 无法通过 128 (在表空间 HIS_TABLESPACE_TEMP 中) 扩展 temp 段

    前言:采用jmeter进行压力测试,大概向oracle 添加了140W条数据. 结果系统涉及到该表的业务都异常卡.访问阿里巴巴的那个druid monitor,因为系统中集成了,查看sql监控中的sq ...

  5. JS框架_(Bootstrap.js)实现简单的轮播图

    Bootstrap框架中 轮播(Carousel)插件是一种灵活的响应式的向站点添加滑块的方式 轮播图效果: <!DOCTYPE html> <html> <head&g ...

  6. less基本用法:持续归纳中

    todo 1,嵌套语法:https://www.w3cschool.cn/less/nested_directives_bubbling.html 简单来说就是可以与html一样去写css,并且会继承 ...

  7. wannafly 挑战赛9 D 造一造 (卡特兰数)

    链接:https://www.nowcoder.com/acm/contest/71/D 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 262144K,其他语言524288K 64b ...

  8. C++入门经典-例3.17-使用while循环进行计算

    1:代码如下: // 3.17.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include <iostream> usin ...

  9. 树莓派安装parrot linux记录

    手头这台树莓派3b安装parrot linux arm遇到了不少问题,写篇博客记录一下. 1.下载和刻录 网址:https://www.parrotsec.org/download-other.php ...

  10. CentOS 6.4编译安装和部署Zabbix 2.0版本监控(中文)

    [一].zabbix简介 zabbix是一个基于web界面的提供分布式系统监视以及网络监视功能的企业级开元解决方案 zabbix由2部分构成,zabbix_server和可选组件zabbix_agen ...