算法 图1 列出连通集

全部每周作业和视频思考题答案和解析 见 浙江大学 数据结构 思考题+每周练习答案汇总

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

输入格式:

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

输出格式:

按照"{ v​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 }

解答:

我倾向于用邻接矩阵来实现这个功能,因为反正也不知道一共有多少条边,邻接矩阵反而更直观一些,如果用邻接表就写起来不是很容易。

首先我们先构建一个二维数组用来存连接图,以及一个一维数组用来记录已经访问过的点。

int Graph[11][11];
bool visit[11];

以及三个基础函数,一个用来读入连接生成图,一个初始化,把所有数据初始化为0(虽然全局变量一开始就是0,不过为了保险起见还是初始化一下),一个是用来恢复visit都变为0,用于下一次遍历。

void initGraph(int N);
void recovGraph(int N);
void generateGra(int E);

核心函数为遍历函数:

void ErgDFS(int N);
void ErgBFS(int N);

深度搜索和广度搜索视频里介绍已经非常详细了,这里不再赘述。直接附带上源码:

#include <iostream>
#include <map>
#include <queue>
#include <vector>
#include <string>
using namespace std;
int Graph[11][11];
bool visit[11];
void initGraph(int N);
void recovGraph(int N);
void generateGra(int E);
void ErgDFS(int N);
void ErgBFS(int N);
int main(void) {
	int N,E;
	cin >> N >> E;
	initGraph(N);
	generateGra(E);
	ErgDFS( N);
	recovGraph(N);
	ErgBFS(N);

	system("pause");
	return 0;
}

void initGraph(int N) {
	for (int i = 0;i < N;i++) {
		visit[i] = 0;
		for (int j = 0;j < N;j++) {
			Graph[i][j] = 0;
			if (i == j) {
				Graph[i][j] = 1;
			}
		}	
	}
}
void recovGraph(int N) {
	for (int i = 0;i < N;i++) {
		visit[i] = 0;
	}
}

void generateGra(int E) {
	
	for (int i = 0;i < E;i++) {
		int a, b,tempA,tempB;
		cin >> a >> b;
		Graph[a][b] = 1;
		Graph[b][a] = 1;
	}
}

void DFS(int i,int N)
{   
	//Graph[i][j].Visit = 1; //
	//遍历i+1--N-1
	visit[i] = 1;
	cout << i << " ";
	for (int k = 0;k < N;k++) {
		if (Graph[i][k] == 1 && visit[k] == 0) {
			visit[k] = 1;
			DFS(k,N);		
		}
	}		
}
void ErgDFS(int N) {
	for (int i = 0;i < N;i++) {
		if (visit[i] == 0) {
			cout << "{ ";
			DFS(i,N);
			cout << "}"<<endl;
		}		
	}
}
queue<int> myQueue;
void BFS(int i, int N)
{
	visit[i] = 1;
	myQueue.push(i);

	while (!myQueue.empty()) {
		int a = myQueue.front();
		myQueue.pop();
		cout << a << " ";
		for (int j = 0;j < N;j++) {
			if (Graph[a][j] == 1 && visit[j] == 0) {
				myQueue.push(j);
				visit[j] = 1;
			}
		}
	}
}

void ErgBFS(int N) {
	for (int i = 0;i < N;i++) {
		if (visit[i] == 0) {
			cout << "{ ";
			BFS(i, N);
			cout << "}" << endl;
		}
	}
}

测试结果如下:

发布了174 篇原创文章 · 获赞 394 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/tiao_god/article/details/105220012