7-6 列出連通集
阿新 • • 發佈:2018-12-18
給定一個有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<stdio.h> #include<stdlib.h> #include<string.h> #define MAXN 15 #define TRUE 1 #define FALSE 0 typedef int Vertex; /* 用頂點下標表示頂點,為整型 */ int Nv,Ne; int G[MAXN][MAXN]; Vertex Visited[MAXN] = {FALSE}; void BuildGraph(); void DFS(Vertex V); void BFS (Vertex S); int main() { Vertex W; BuildGraph(); for(W=0; W<Nv; W++){ if( !Visited[W] ){//若W頂點未被訪問過 printf("{ "); DFS(W); printf("}\n"); } } memset(Visited,0,sizeof(Visited)); for(W=0; W<Nv; W++){ if( !Visited[W] ){//若W頂點未被訪問過 printf("{ "); BFS(W); printf("}\n"); } } return 0; } void BuildGraph() { int i,j; int v1,v2; scanf("%d",&Nv); for(i=0; i<Nv; i++) for(j=0; j<Nv; j++) G[i][j] = 0; scanf("%d",&Ne); for(i=0; i<Ne; i++){ scanf("%d %d",&v1,&v2); G[v1][v2] = 1; G[v2][v1] = 1; } } void DFS(Vertex V) {/* 以V為出發點對鄰接矩陣儲存的圖G進行DFS搜尋 */ Vertex W; printf("%d ", V); /*訪問第V個頂點 */ Visited[V] = TRUE; /*標記V已訪問 */ for(W=0; W<Nv; W++){ if( G[V][W] != 0){ /* 對V的每個鄰接點W */ if( !Visited[W] ){ //若W未被訪問過 DFS(W); /* 則遞迴訪問之 */ } } } } void BFS (Vertex S) { /*以S為出發點對鄰接矩陣儲存的圖G進行BFS搜尋 */ Vertex V, W; Vertex s[MAXN]; //頂點佇列 int head = 0,tail = 0; printf("%d ", S); /*訪問第V個頂點 */ Visited[S] = TRUE; /* 標記S已訪問 */ s[tail++] = S; while ( head < tail ) { //佇列不為空時 V = s[head++]; /* 彈出V */ for(W=0; W<Nv; W++) /* 對圖中的每個頂點W */ /* 若W是V的鄰接點並且未訪問過 */ if ( !Visited[W] && G[V][W] ){ /* 訪問頂點W */ printf("%d ", W); /*訪問第V個頂點 */ Visited[W] = TRUE; /* 標記W已訪問 */ s[tail++] = W; /* W入佇列 */ } } /* while結束*/ }