1. 程式人生 > >06-圖1 列出連通集

06-圖1 列出連通集

ups struct bsp 入隊 lin scan ted visit nbsp

給定一個有N個頂點和E條邊的無向圖,請用DFS和BFS分別列出其所有的連通集。假設頂點從0到N?1編號。進行搜索時,假設我們總是從編號最小的頂點出發,按編號遞增的順序訪問鄰接點。

輸入格式:

輸入第1行給出2個整數N(0)和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 }

  1 #include<stdio.h>
  2 #include<stdlib.h>
  3 #define Max 10
  4 
  5 bool Visited[Max];         //全局數組,記錄每個結點是否被遍歷 
  6 
  7 struct GNode{
  8     int Data[Max][Max];
  9     int Nv;
 10     int Ne;
 11 };
 12 typedef struct GNode *Graph;
 13 
 14 //建立鄰接矩陣存儲的空圖 
 15 Graph BuildGraph(int N, int
E){ 16 Graph G = (Graph)malloc(sizeof(struct GNode)); 17 for(int i=0; i<Max; i++){ 18 for(int j=0; j<Max; j++){ 19 G->Data[i][j] = 0; //0表示沒有邊,1表示有邊 20 } 21 } 22 G->Nv = N; 23 G->Ne = E; 24 return G; 25 } 26 27 //讀入圖的邊
28 void ReadEdge(Graph G, int E){ 29 int e1, e2; 30 for(int i=0; i<E; i++) { 31 scanf("%d %d", &e1, &e2); 32 G->Data[e1][e2] = 1; 33 G->Data[e2][e1] = 1; 34 } 35 } 36 37 //初始化Visited[]為全false 38 void InitVisited( ){ 39 for(int i=0; i<Max; i++){ 40 Visited[i] = false; 41 } 42 } 43 44 //深度優先遍歷 45 void DFS(Graph G, int V){ 46 printf("%d ", V); //訪問V 47 Visited[V] = true; //將Visited[V]置為已被訪問過 48 for(int j=0; j<G->Nv; j++){ 49 if(G->Data[V][j]==1 && Visited[j]==false){ //選出與V相連且未被訪問過的結點 50 DFS(G, j); //遞歸地進行深度優先遍歷 51 } 52 } 53 } 54 55 struct QNode{ 56 int *data; 57 int front, rear; 58 int maxsize; 59 }; 60 typedef struct QNode *Queue; 61 62 //判斷隊列是否空函數 63 bool IsEmpty(Queue Q){ 64 return (Q->rear == Q->front); 65 } 66 67 //建立一個空隊列 68 Queue BuildQ(int N){ 69 Queue Q = (Queue)malloc(sizeof(struct QNode)); 70 Q->data = (int*)malloc(sizeof(int)*N); 71 Q->front = Q->rear = 0; 72 Q->maxsize = N; 73 return Q; 74 } 75 76 //入隊函數 77 void AddQ(Queue Q, int X){ 78 Q->rear = (Q->rear + 1)%Q->maxsize ; 79 Q->data[Q->rear] = X; 80 } 81 82 //出隊函數 83 int DeleteQ(Queue Q){ 84 Q->front = (Q->front + 1)%Q->maxsize; 85 return Q->data[Q->front]; 86 } 87 88 //廣度優先遍歷 89 void BFS(Graph G, int V){ 90 Queue Q = BuildQ(G->Nv); 91 printf("%d ", V); //訪問V 92 Visited[V] = true; //將Visited[V]置為已被訪問過 93 AddQ(Q, V); //將V入隊 94 while(!IsEmpty(Q)){ //當隊列不空 95 int W = DeleteQ(Q); //取出隊頭元素 96 for(int i=0; i<G->Nv; i++){ 97 if(!Visited[i] && G->Data[W][i]==1){ //選出與隊頭元素相連且未被訪問過的元素 98 printf("%d ", i); 99 Visited[i] = true; 100 AddQ(Q, i); 101 } 102 } 103 } 104 } 105 106 int main(){ 107 int N, E; 108 scanf("%d %d", &N, &E); 109 Graph G = BuildGraph(N, E); //建立鄰接矩陣儲存的圖 110 ReadEdge(G, E); //讀入圖的邊 111 InitVisited(); 112 for(int i=0; i<G->Nv; i++){ 113 if(Visited[i]==false){ 114 printf("{ "); 115 DFS(G, i); 116 printf("}\n"); 117 } 118 } 119 InitVisited(); //每次遍歷前要將Visited[]初始化 120 for(int i=0; i<G->Nv; i++){ 121 if(Visited[i]==false){ 122 printf("{ "); 123 BFS(G, i); 124 printf("}\n"); 125 } 126 } 127 return 0; 128 }

 

06-圖1 列出連通集