列出连通集(DFS及BFS遍历图) -- 数据结构
题目:
给定一个有N个顶点和E条边的无向图,请用DFS和BFS分别列出其所有的连通集。假设顶点从0到N−1编号。进行搜索时,假设我们总是从编号最小的顶点出发,按编号递增的顺序访问邻接点。
输入格式:
输入第1行给出2个整数N(0<N≤10)和E,分别是图的顶点数和边数。随后E行,每行给出一条边的两个端点。每行中的数字之间用1空格分隔。
输出格式:
按照 “ { v1, v2, v3, ... ,vk } ”的格式,每行输出一个连通集。先输出DFS的结果,再输出BFS的结果。
1 v2 ... vk }"的格式,每行输出一个连通集。先输出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遍历图) -- 数据结构的更多相关文章
- 图的DFS与BFS遍历
一.图的基本概念 1.邻接点:对于无向图无v1 与v2之间有一条弧,则称v1与v2互为邻接点:对于有向图而言<v1,v2>代表有一条从v1到v2的弧,则称v2为v1的邻接点. 2.度:就是 ...
- 邻接矩阵实现图的存储,DFS,BFS遍历
图的遍历一般由两者方式:深度优先搜索(DFS),广度优先搜索(BFS),深度优先就是先访问完最深层次的数据元素,而BFS其实就是层次遍历,每一层每一层的遍历. 1.深度优先搜索(DFS) 我一贯习惯有 ...
- 数据结构上机实验dfs&&bfs遍历图
#include<stdio.h> #include<string.h> #include<stdlib.h> #include<queue> #inc ...
- DFS和BFS遍历的问题
来自https://github.com/soulmachine/leetcode 广度优先搜索 输入数据:没有什么特征,不像dfs需要有递归的性质.如果是树/图,概率更大. 状态转换图:数或者DAG ...
- 判断图连通的三种方法——dfs,bfs,并查集
Description 如果无向图G每对顶点v和w都有从v到w的路径,那么称无向图G是连通的.现在给定一张无向图,判断它是否是连通的. Input 第一行有2个整数n和m(0 < n,m < ...
- 图的bfs遍历模板(邻接矩阵存储和邻接表存储)
bfs遍历图模板伪代码: bfs(u){ //遍历u所在的连通块 queue q; //将u入队 inq[u] = true; while (q非空){ //取出q的队首元素u进行访问 for (从u ...
- 数据结构(三十二)图的遍历(DFS、BFS)
图的遍历和树的遍历类似.图的遍历是指从图中的某个顶点出发,对图中的所有顶点访问且仅访问一次的过程.通常有两种遍历次序方案:深度优先遍历和广度优先遍历. 一.深度优先遍历 深度优先遍历(Depth_Fi ...
- [数据结构]图的DFS和BFS的两种实现方式
深度优先搜索 深度优先搜索,我们以无向图为例. 图的深度优先搜索(Depth First Search),和树的先序遍历比较类似. 它的思想:假设初始状态是图中所有顶点均未被访问,则从某个顶点v出发, ...
- PTA 2-1 列出连通集【DFS+BFS基础】
给定一个有N个顶点和E条边的无向图,请用DFS和BFS分别列出其所有的连通集.假设顶点从0到N−1编号.进行搜索时,假设我们总是从编号最小的顶点出发,按编号递增的顺序访问邻接点. 输入格式: 输入第1 ...
随机推荐
- 字典树Trie--实现敏感词过滤
序言 Trie树 资料 https://blog.csdn.net/m0_37907797/article/details/103272967?utm_source=apphttps://blog.c ...
- LOJ #2718. 「NOI2018」归程 Dijkstra+可持久化并查集
把 $Noi2018$ day1t1 想出来还是挺开心的,虽然是一道水题~ 预处理出来 1 号点到其它点的最短路,然后预处理边权从大到小排序后加入前 $i$ 个边的并查集. 这个并查集用可持久化线段树 ...
- CMS 与 框架
Framework:框架.是整合的工具集,基于编程语言.可以帮助我们快速开发网站.比较常见的是J2EE(基于Java),Symfony2(基于PHP),Django(基于Python),Ruby on ...
- hihocoder周赛(树的最长距离)
题目4 : 道路建设 时间限制:20000ms 单点时限:1000ms 内存限制:256MB 描述 H 国有 n 座城市和 n-1 条无向道路,保证每两座城市都可以通过道路互相到达.现在 H 国要开始 ...
- codevs 2597 团伙x
题目描述 Description 1920年的芝加哥,出现了一群强盗.如果两个强盗遇上了,那么他们要么是朋友,要么是敌人.而且有一点是肯定的,就是: 我朋友的 ...
- HGOI 20191106
HGOI 20191106 t1 旅行家(traveller) 2s,256MB [题目背景] 小X热爱旅行,他梦想有一天可以环游全世界-- [题目描述] 现在小X拥有n种一次性空间转移装置,每种装置 ...
- 【BZOJ3545&BZOJ3551】Peaks(kruskal重构树,主席树,dfs序)
题意:在Bytemountains有N座山峰,每座山峰有他的高度h_i. 有些山峰之间有双向道路相连,共M条路径,每条路径有一个困难值,这个值越大表示越难走, 现在有Q组询问,每组询问询问从点v开始只 ...
- win7,win10 系统上搭建testlink1.9.18环境实操步骤
Windows7,10系统上安装TestLink1.9.18(基于xampp) 写于:2018.11.28 二次排版微调:2019.01.01 如遇本文资料缺失,可点击百度网盘查看原始资料. 链接:h ...
- C++入门经典-例5.2-使用指针比较两个数的大小
1:代码如下: // 5.2.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include <iostream> using ...
- 机器学习模型解释工具-Lime
本篇文章转载于LIME:一种解释机器学习模型的方法 该文章介绍了一种模型对单个样本解释分类结果的方法,区别于对整体测试样本的评价指标准确率.召回率等,Lime为具体某个样本的分类结果做出解释,直观地表 ...