5-6 列出连通集 (25分)
给定一个有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 }
参考了coffee-123的方法用数组代替队列
http://blog.csdn.net/u014376961/article/details/52120596
#include <stdio.h> #include <stdlib.h> #include <string.h> int G[10][10];/*采用领接矩阵的方法来表示*/ int visit[10];/*表示每个顶点*/ void DFS(int i,int N) { int j; visit[i] = 1;/*标记访问过*/ printf(" %d",i); for(j = 0; j < N; j++)/*寻找顶点i的下一个领接顶点*/ { if(!visit[j]&&G[i][j])/*找到后就将找到后的顶点进行递归DFS*/ { DFS(j,N); } } } void BFS(int i,int N) { int queue[10]= {0};/*用一维数组来模拟队列*/ int rear,front,v,j; rear = front = -1; visit[i] = 1; queue[++rear] = i;/*入队*/ while(front < rear) { v = queue[++front];/*出队*/ printf(" %d",v); for(j = 0 ; j < N; j++)/*找到当前顶点的所有邻接点(从小到大)加入到队列中去*/ { if(!visit[j] && G[v][j]) { visit[j] = 1;/*标记访问过*/ queue[++rear] = j;/*入队*/ } } } } int main(void) { int N,E; int v1,v2; scanf("%d %d",&N,&E); for(int i = 0; i < E; i++) { scanf("%d %d",&v1,&v2); G[v1][v2] = G[v2][v1] = 1; } memset(visit,0,sizeof(visit));/*数组清零*/ for(int i = 0 ;i < N; i++)/*DFS*/ { if(!visit[i]) { printf("{"); DFS(i,N); printf(" }\n"); } } memset(visit,0,sizeof(visit));/*数组清零*/ for(int i = 0; i < N; i++)/*BFS*/ { if(!visit[i]) { printf("{"); BFS(i,N); printf(" }\n"); } } return 0; }