给定一个有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 }
解答:
#include<stdio.h>
#include<stdlib.h>
#define CLOSE 0
void DFS(int vertex);
void BFS(int vertex);
int getNext(int y,int x);
int getInsideNext(int y);
int matrix[12][12];
int isVisited[12]={0};
int n;
int main(){
int e;
scanf("%d%d",&n,&e);
for(int i=0; i<n; i++){
for(int j=0; j<n; j++){
matrix[i][j]=CLOSE;
}
}
int y,x;
for(int i=0; i<e; i++){
scanf("%d%d",&y,&x);
matrix[y][x]=1;
matrix[x][y]=1;
}
for(int i=0; i<n; i++){
if(!isVisited[i]){
printf("{");
DFS(i);
int flag=1;
for(int j=0; j<n; j++){
if(!isVisited[j]){
printf(" }\n");
flag=0;
break;
}
}
if(flag){
printf(" }\n");
}
}
}
for(int i=0; i<12; i++)
isVisited[i]=0;
for(int i=0; i<n; i++){
if(!isVisited[i]){
printf("{");
BFS(i);
int flag=1;
for(int j=0; j<n; j++){
if(!isVisited[j]){
printf(" }\n");
flag=0;
break;
}
}
if(flag){
printf(" }");
}
}
}
return 0;
}
int getInsideNext(int y){
for(int x=0; x<n; x++){
if(matrix[y][x]!=CLOSE){
return x;
}
}
return -1;
}
int getNext(int y,int x){
for(int i=x+1; i<n; i++) {
if(matrix[y][i]!=CLOSE) {
return i;
}
}
return -1;
}
//深度优先遍历
void DFS(int vertex){
printf(" %d",vertex);
isVisited[vertex]=1;
int w=getInsideNext(vertex);
while(w!=-1){
if(!isVisited[w]){
DFS(w);
}
w=getNext(vertex,w);
}
}
//广度优先遍历
void BFS(int vertex){
if(!isVisited[vertex])
printf(" %d",vertex);
isVisited[vertex]=1;
int size=0;
int da[12]={0};
for(int x=0; x<n; x++){
if(matrix[vertex][x]!=CLOSE && !isVisited[x]){
printf(" %d",x);
da[size++]=x;
isVisited[x]=1;
}
}
for(int i=0; i<size; i++){
BFS(da[i]);
}
}