7-6 列出连通集 (25分)

文章目录

  • 问题
  • 解决方法
    • 递而不归+队列
    • 递而不归+STL 队列
  • 后记

问题

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

输入第1行给出2个整数N(0 输出格式:

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

解决方法

递而不归+队列

DFS类似于先序遍历,采用递归实现;BFS类似于层序遍历采用队列实现.

#include
#include
#define MAXN 10
using namespace std;
int Nv, Ne;
int Visited[MAXN], Graph[MAXN][MAXN];
void CreateGraph()
{
	cin >> Nv >> Ne;
	int x, y;
	for (int i = 0; i < Ne; i++)
	{
		cin >> x >> y;
		Graph[x][y] = Graph[y][x] = 1;
	}
}
void DFS(int i)
{
	Visited[i] = 1;
	cout << " " << i;
	for (int j = 0; j < Nv; j++)
	{
		if (!Visited[j] && Graph[i][j])
		{
			DFS(j);
		}
	}
}
void BFS(int i)
{
	int temp,front = -1, rear = -1;
	int Queue[MAXN];
	Visited[i] = 1;
	Queue[++rear] = i;
	while (front < rear)
	{
		temp = Queue[++front];
		cout << " " << temp;
		for (int i = 0; i < Nv; i++)
		{
			if (!Visited[i] && Graph[temp][i])
			{
				Visited[i] = 1;
				Queue[++rear] = i;
			}
		}
	}
}
int main()
{
	CreateGraph();
	memset(Visited, 0, sizeof(Visited));
	for (int i = 0; i < Nv; i++)
	{
		if (!Visited[i])
		{
			cout << "{";
			DFS(i);
			cout << " }" << endl;
		}
	}
	memset(Visited, 0, sizeof(Visited));
	for (int i = 0; i < Nv; i++)
	{
		if (!Visited[i])
		{
			cout << "{";
			BFS(i);
			cout <<" }" << endl;
		}
	}
	return 0;
}


递而不归+STL 队列

#include<iostream>
#include<string.h>
#include<queue>
#define MAXN 10
using namespace std;
int Nv, Ne;
queue<int>q;
int Visited[MAXN], Graph[MAXN][MAXN];
void CreateGraph()
{
	int x, y;
	cin >> Nv >> Ne;
	for (int i = 0; i < Ne; i++)
	{
		cin >> x >> y;
		Graph[x][y] = Graph[y][x] = 1;
	}
}
void DFS(int i)
{
	Visited[i] = 1;
	cout << " " << i;
	for (int j = 0; j< Nv; j++)
	{
		if (!Visited[j] && Graph[i][j]) DFS(j);
	}
}
void BFS(int i)
{
	q.push(i);
	Visited[i] = 1;
	while (!q.empty())
	{
		for (int j = 0; j <= Nv; j++)
		{
			if (!Visited[j] && Graph[q.front()][j])
			{
				Visited[j] = 1;
				q.push(j);
			}
		}
		cout << " " << q.front();
		q.pop();
	}
}
int main()
{
	CreateGraph();
	memset(Visited, 0, sizeof(Visited));
	for (int i = 0; i < Nv; i++)
	{
		if (!Visited[i])
		{
			cout << "{";
			DFS(i);
			cout << " }" << endl;
		}
	}
	memset(Visited, 0, sizeof(Visited));
	for (int i = 0; i < Nv; i++)
	{
		if (!Visited[i])
		{
			cout << "{";
			BFS(i);
			cout << " }" << endl;
		}
	}
	return 0;
}


后记

1.memset的用法参考:memset的用法,在这个题中用于对数组Visited的初始化.
2.STL中的队列的使用有些地方有些忘记了,需要复习.
3.说实话,我感觉这两个版本的代码是一样的,只是用STL的队列替换C语言的队列,好吃就是复习了一下STL的队列╮(╯▽╰)╭.

你可能感兴趣的:(7-6 列出连通集 (25分))