目录
7-1 图的先深搜索
输出无向图的给定起点的先深序列。
输入格式:
输入第一行给出三个正整数,分别表示无向图的节点数N(1<N≤10)、边数M(≤50)和探索起始节点编号S(节点从1到N编号)。
随后的M行对应M条边,每行给出一对正整数,分别是该条边直接连通的两个节点的编号。
输出格式:
输出从S开始的无向图的先深搜索序列,用一个空格隔开,最后也有一个空格;如果为非连通图,再在结尾处另起一行输出一个0,表示此图非连通。
由于深度优先遍历的节点序列是不唯一的,为了使得输出具有唯一的结果,我们约定以表头插入法构造邻接表。
输入样例1:
6 8 2
1 2
2 3
3 4
4 5
5 6
6 4
3 6
1 5
输出鲜例1:
2 3 6 4 5 1
输入样例2:
4 3 1
1 2
2 3
3 1
输出样例1:
1 3 2
0
7-2 图的先广搜索
输出无向图的给定起点的先广序列。
输入格式:
输入第一行给出三个正整数,分别表示无向图的节点数N(1<N≤10)、边数M(≤50)和探索起始节点编号S(节点从1到N编号)。
随后的M行对应M条边,每行给出一对正整数,分别是该条边直接连通的两个节点的编号。
输出格式:
输出从S开始的无向图的先广搜索序列,用一个空格隔开,最后也有一个空格;如果为非连通图,再在结尾处另起一行输出一个0,表示此图非连通。
由于广度优先遍历的节点序列是不唯一的,为了使得输出具有唯一的结果,我们约定以表头插入法构造邻接表。
输入样例:
6 8 2
1 2
2 3
3 4
4 5
5 6
6 4
3 6
1 5
输出样例:
2 3 1 6 4 5
AC代码:
链式前向星存储的邻接表遍历
/*
* @Author: Spare Lin
* @Project: AcWing2022
* @Date: 2022/7/21 17:22
* @Description: 7-1 图的先深搜索 作者 唐艳琴 单位 中国人民解放军陆军工程大学
* @URL: https://pintia.cn/problem-sets/1456491351779704832/problems/1456491629799145472
*/
#include <iostream>
#include <cstring>
using namespace std;
const int N = 15, M = N * 2;
int h[N], e[M], ne[M], idx;
bool st[N];
int n, m, s, cnt;
void add(int a, int b) {
e[idx] = b, ne[idx] = h[a], h[a] = idx++;
}
void dfs(int u) {
st[u] = true;
cout << u << ' ';
cnt++;
for (int i = h[u]; i != -1; i = ne[i]) { //遍历访问u的子节点
int j = e[i];
if (!st[j]) {
dfs(j);//可以返回搜索的子树大小
}
}
}
int main() {
cin >> n >> m >> s;
memset(h, -1, sizeof h); //头节点指向-1
for (int i = 0; i < m; i++) {
int a, b;
cin >> a >> b;
add(a, b), add(b, a);//建立无向图
}
dfs(s);
cout << (cnt != n ? "\n0" : "");
return 0;
}
/*
* @Author: Spare Lin
* @Project: AcWing2022
* @Date: 2022/7/21 17:25
* @Description: 7-2 图的先广搜索 作者 唐艳琴 单位 中国人民解放军陆军工程大学
* @URL: https://pintia.cn/problem-sets/1456491351779704832/problems/1456491629799145473
*/
#include <iostream>
#include <cstring>
#include <queue>
#include <algorithm>
using namespace std;
const int N = 15, M = N * 2;
int h[N], e[M], ne[M], idx;
int n, m, s, cnt;
bool st[N];
void add(int a, int b) {
e[idx] = b, ne[idx] = h[a], h[a] = idx++;
}
void bfs(int u) {
st[u] = true;
cnt++;
queue<int> q;
q.push(u);
cout << u << ' ';
while (q.size()) {
int t = q.front();
q.pop();
for (int i = h[t]; i != -1; i = ne[i]) {
int j = e[i];
if (!st[j]) {
st[j] = true;
cnt++;
cout << j << ' ';
q.push(j);
}
}
}
}
int main() {
cin >> n >> m >> s;
memset(h, -1, sizeof h); //头节点指向-1
for (int i = 0; i < m; i++) {
int a, b;
cin >> a >> b;
add(a, b), add(b, a);//建立无向图
}
bfs(s);
cout << (cnt != n ? "\n0" : "");
return 0;
}
邻接表存图遍历
/*
* @Author: Spare Lin
* @Project: AcWing2022
* @Date: 2022/7/21 17:36
* @Description: 7-1 图的先深搜索 7-2 图的先广搜索
* @URL: https://pintia.cn/problem-sets/1456491351779704832/problems/1456491629799145472
*/
#include <iostream>
#include <cstring>
#include <queue>
using namespace std;
const int MAXV = 15;
typedef struct ANode { //边结点定义
int adjvex; //该边的终点编号
int weight; //该边的权值
struct ANode *nextarc; //指向下一条边的指针
} ArcNode;//边结点类型
typedef struct Vnode { //顶点结点定义
//char data[MAXL]; //顶点其他信息
int vno; //改为顶点编号
ArcNode *firstarc; //指向第一条边
} VNode;//邻接表头结点类型
typedef VNode AdjList[MAXV];//AdjList是邻接表类型(用来定义结点数组)
typedef struct {
AdjList adjlist; //邻接表
int n, e; //图中顶点数n和边数e
} ALGraph;//图结构类型
ALGraph *g = (ALGraph *) malloc(sizeof(ALGraph));//图结构
int visited[MAXV];
int cnt; //全局变量:计数器,统计遍历到的顶点总数
//建立无向图的邻接表
void CreateAdj(int n, int e) {
int i, x, y;
for (i = 1; i <= n; i++) {
g->adjlist[i].vno = i;
g->adjlist[i].firstarc = NULL;
}
for (i = 1; i <= e; i++) {
scanf("%d%d", &x, &y);
//以x->y的边,创建边结点,并把它添加到顶点x引出的单链表的最前面
ArcNode *arcnode = (ArcNode *) malloc(sizeof(ArcNode));
arcnode->adjvex = y;
arcnode->nextarc = g->adjlist[x].firstarc;
g->adjlist[x].firstarc = arcnode; //插入作为顶点x的第一条边
//以y->x的边,创建边结点,并把它添加到顶点x引出的单链表的最前面
arcnode = (ArcNode *) malloc(sizeof(ArcNode));
arcnode->adjvex = x;
arcnode->nextarc = g->adjlist[y].firstarc;
g->adjlist[y].firstarc = arcnode; //插入作为顶点x的第一条边
}
g->n = n;
g->e = e;
}
//输出图的邻接表
void DispAdj() {
int i;
ArcNode *p;
for (i = 1; i <= g->n; i++) {
p = g->adjlist[i].firstarc;
while (p != NULL) {
printf("→%d", p->adjvex);
p = p->nextarc;
}
printf("→∧\n");
}
}
//销毁图的邻接表
void DestroyAdj() {
int i;
ArcNode *pre, *p;
for (i = 1; i <= g->n; i++) {
pre = g->adjlist[i].firstarc;
while (pre != NULL) {
p = pre->nextarc;
free(pre);
pre = p;
}
}
free(g);
}
void DFS(int v) {//邻接表的DFS算法
ArcNode *p; //指向边结点的指针
printf("%d ", v); //输出被访问顶点的编号
visited[v] = 1; //置已访问标记
cnt++; //计数器加1
p = g->adjlist[v].firstarc; //p指向顶点v的第一个邻接点
while (p != NULL) {
if (visited[p->adjvex] == 0) //若p->adjvex顶点未访问,递归访问它
DFS(p->adjvex);
p = p->nextarc; //p指向顶点v的下一个邻接点
}
}
void BFS(int v) { //邻接表的BFS算法
ArcNode *p; //指向边结点的指针
queue<int> qu; //定义一个队列qu
int w; //定义存放顶点的访问标志的数组
printf("%d ", v); //输出被访问顶点的编号
cnt++; //计数器加1
visited[v] = 1; //置已访问标记
qu.push(v); //v进队
while (!qu.empty()) { //队列不空时循环
w = qu.front();
qu.pop(); //出队顶点w
p = g->adjlist[w].firstarc; //找顶点w的第一个邻接点
while (p != NULL) {
if (visited[p->adjvex] == 0) { //若当前邻接顶点未被访问
printf("%d ", p->adjvex);//访问相邻顶点
cnt++; //计数器加1
visited[p->adjvex] = 1; //置该顶点已被访问的标志
qu.push(p->adjvex); //该顶点进队
}
p = p->nextarc; //找顶点w的下一个邻接点
}
}
}
int main() {
int n, e, s;
while (scanf("%d%d%d", &n, &e, &s)) {
CreateAdj(n, e);
//测试输出
// DispAdj();
memset(visited, 0, sizeof(visited)); //初始化访问标志
cnt = 0;
// DFS(s);
BFS(s);
if (cnt < n) {
printf("\n0");
}
}
//以下是销毁工作,记得去做
DestroyAdj();
return 0;
}
邻接表存图遍历(vector + queue)
/*
* @Author: Spare Lin
* @Project: AcWing2022
* @Date: 2022/7/21 20:35
* @Description: 7-1 图的先深搜索 7-2 图的先广搜索
* @URL: https://pintia.cn/problem-sets/1456491351779704832/problems/1456491629799145472
*/
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
const int N = 15;
vector<int> h[N];
bool st[N];
int n, m, s, cnt;
void dfs(int u) {
cout << u << ' ';
st[u] = true;
cnt++;
for (auto j : h[u]) {
if (!st[j]) {
dfs(j);
}
}
}
void bfs(int u) {
queue<int> q;
q.push(u);
while (!q.empty()) {
int t = q.front();
q.pop();
if(!st[t]) {
st[t] = true;
cout << t << ' ';
cnt++;
for (auto x: h[t]) {
q.push(x);
}
}
}
}
int main() {
cin >> n >> m >> s;
while (m--) {
int a, b;
cin >> a >> b;
h[a].insert(h[a].begin(), b);
h[b].insert(h[b].begin(), a);//建立无向图
}
dfs(s);
//bfs(s);
cout << (cnt != n ? "\n0" : "");
return 0;
}