题目:

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. 字典树Trie--实现敏感词过滤

    序言 Trie树 资料 https://blog.csdn.net/m0_37907797/article/details/103272967?utm_source=apphttps://blog.c ...

  2. LOJ #2718. 「NOI2018」归程 Dijkstra+可持久化并查集

    把 $Noi2018$ day1t1 想出来还是挺开心的,虽然是一道水题~ 预处理出来 1 号点到其它点的最短路,然后预处理边权从大到小排序后加入前 $i$ 个边的并查集. 这个并查集用可持久化线段树 ...

  3. CMS 与 框架

    Framework:框架.是整合的工具集,基于编程语言.可以帮助我们快速开发网站.比较常见的是J2EE(基于Java),Symfony2(基于PHP),Django(基于Python),Ruby on ...

  4. hihocoder周赛(树的最长距离)

    题目4 : 道路建设 时间限制:20000ms 单点时限:1000ms 内存限制:256MB 描述 H 国有 n 座城市和 n-1 条无向道路,保证每两座城市都可以通过道路互相到达.现在 H 国要开始 ...

  5. codevs 2597 团伙x

                         题目描述 Description 1920年的芝加哥,出现了一群强盗.如果两个强盗遇上了,那么他们要么是朋友,要么是敌人.而且有一点是肯定的,就是: 我朋友的 ...

  6. HGOI 20191106

    HGOI 20191106 t1 旅行家(traveller) 2s,256MB [题目背景] 小X热爱旅行,他梦想有一天可以环游全世界-- [题目描述] 现在小X拥有n种一次性空间转移装置,每种装置 ...

  7. 【BZOJ3545&BZOJ3551】Peaks(kruskal重构树,主席树,dfs序)

    题意:在Bytemountains有N座山峰,每座山峰有他的高度h_i. 有些山峰之间有双向道路相连,共M条路径,每条路径有一个困难值,这个值越大表示越难走, 现在有Q组询问,每组询问询问从点v开始只 ...

  8. win7,win10 系统上搭建testlink1.9.18环境实操步骤

    Windows7,10系统上安装TestLink1.9.18(基于xampp) 写于:2018.11.28 二次排版微调:2019.01.01 如遇本文资料缺失,可点击百度网盘查看原始资料. 链接:h ...

  9. C++入门经典-例5.2-使用指针比较两个数的大小

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

  10. 机器学习模型解释工具-Lime

    本篇文章转载于LIME:一种解释机器学习模型的方法 该文章介绍了一种模型对单个样本解释分类结果的方法,区别于对整体测试样本的评价指标准确率.召回率等,Lime为具体某个样本的分类结果做出解释,直观地表 ...