给定一个有N个顶点和E条边的无向图,请用DFS和BFS分别列出其所有的连通集。假设顶点从0到N−1编号。进行搜索时,假设我们总是从编号最小的顶点出发,按编号递增的顺序访问邻接点。
输入格式:
输入第1行给出2个整数N(0<N≤10)和E,分别是图的顶点数和边数。随后E行,每行给出一条边的两个端点。每行中的数字之间用1空格分隔。
输出格式:
按照"{ v1 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 }
#include<iostream>
using namespace std;
int Visited[100]={0};
int G[100][100]={0};
void DFS(int i,int n);
void BFS(int i,int n);
int main(void) {
int Nv, Ne, i, x, y;
cin >> Nv >> Ne;
//读取邻接矩阵边的数据
for(i = 0; i < Ne; ++i){
cin >> x >> y;
G[x][y] = G[y][x] = 1;
}
for(i = 0; i < Nv; ++i){
if(Visited[i] == 0){
cout << "{";
DFS(i, Nv);
cout << " }\n";
}
}
//重置顶点访问标记
for(i = 0; i < Nv; ++i)
Visited[i] = 0;
for(i = 0; i < Nv; ++i){
if(Visited[i] == 0){
cout << "{";
BFS(i, Nv);
cout << " }\n";
}
}
}
void DFS(int i,int Nv) {
//该顶点被遍历,标记访问值
cout << " " << i;
Visited[i] = 1;
//j顶点没有被访问过,且i顶点与j顶点有边
//以j顶点为新顶点,递归DFS函数
for(int j = 0; j < Nv; ++j)
if(Visited[j] == 0 && G[i][j] == 1)
DFS(j, Nv);
}
void BFS(int i,int Nv) {
//x、y模拟队列 -1表示当前元素不存在
int v, x = -1, y = -1, queue[100];
//下一元素入队
queue[++x] = i;
Visited[i] = 1;
while(1){
//x y相等时即队列空 停止输出
if(x == y) break;
//元素出列
v = queue[++y];
cout << " " << v;
for(int j = 0; j < Nv; ++j) {
if(Visited[j] == 0 && G[v][j] == 1) {
queue[++x] = j;
Visited[j] = 1;
}
}
}
}