列出连通集 (25分)【C语言】

    技术2022-07-15  75

    题目:

    给定一个有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 }

    算法

    算法描述

    建邻接表图列出连通集子集(DFS)列出连通集子集(BFS)

    提示:邻接表中插入边时,要根据邻接点的大小排序插入

    代码实现

    int main() { int N,E; scanf("%d%d",&N,&E); LGraph G=CreatGraph(N,E); { Edge edge=(PtrToENode)malloc(sizeof(struct ENode)); int i; for(i=0;i<E;i++){ scanf("%d %d",&(edge->V),&(edge->W)); InsertEdge(G,edge); } free(edge); } ListComponent(G,DFS); { int i; for(i=0;i<G->vertexNumber;i++){ visited[i]=0; } } ListComponent(G,BFS); FreeGraph(G); return 0; }

    图的基本操作:图的创建、边的插入、释放图空间

    #define MAXVERTEXNUM 10 typedef int Vertex; int visited[MAXVERTEXNUM]; int queue[MAXVERTEXNUM]; int rear=-1,head=-1; typedef struct ENode* PtrToENode; struct ENode{ Vertex V; Vertex W; }; typedef PtrToENode Edge; typedef struct AdjVNode* PtrToAdjVNode; struct AdjVNode{ Vertex AdjV; PtrToAdjVNode Next; }; typedef struct HNode{ PtrToAdjVNode FirstAdjV; }AdjList[MAXVERTEXNUM]; typedef struct Graph* LGraph; struct Graph{ int vertexNumber; int edgeNumber; AdjList GraphList; }; LGraph CreatGraph(int N,int E) { LGraph G=(LGraph)malloc(sizeof(struct Graph)); G->vertexNumber=N; G->edgeNumber=E; Vertex i; for(i=0;i<N;i++){ G->GraphList[i].FirstAdjV=NULL; } return G; } void InsertEdge(LGraph G,PtrToENode E) { PtrToAdjVNode VAdjNode=(PtrToAdjVNode)malloc(sizeof(struct AdjVNode)); VAdjNode->AdjV=E->W; PtrToAdjVNode L=G->GraphList[E->V].FirstAdjV; if(L==NULL||L->AdjV>E->W){ VAdjNode->Next=L; G->GraphList[E->V].FirstAdjV=VAdjNode; }else{ for(;L->Next&&L->Next->AdjV<E->W;L=L->Next); VAdjNode->Next=L->Next; L->Next=VAdjNode; } PtrToAdjVNode AdjVNode=(PtrToAdjVNode)malloc(sizeof(struct AdjVNode)); AdjVNode->AdjV=E->V; L=G->GraphList[E->W].FirstAdjV; if(L==NULL||L->AdjV>E->V){ AdjVNode->Next=L; G->GraphList[E->W].FirstAdjV=AdjVNode; }else{ for(;L->Next&&L->Next->AdjV<E->V;L=L->Next); AdjVNode->Next=L->Next; L->Next=AdjVNode; } } void FreeGraph(LGraph G) { Vertex i=0; PtrToAdjVNode AdjNode; PtrToAdjVNode T; for(i=0;i<G->vertexNumber;i++){ AdjNode=G->GraphList[i].FirstAdjV; if(AdjNode!=NULL){ T=AdjNode->Next; while(AdjNode){ free(AdjNode); AdjNode=T; if(T){ T=T->Next; } } } } }

    DFS

    void DFS(LGraph G,int V) { if(visited[V]==0){ visited[V]=1; printf(" %d",V); PtrToAdjVNode W=G->GraphList[V].FirstAdjV; for(;W;W=W->Next){ if(visited[W->AdjV]==0){ DFS(G,W->AdjV); } } } }

    BFS

    void BFS(LGraph G,int V) { if(visited[V]==0){ visited[V]=1; printf(" %d",V); queue[++rear]=V; while(rear>head){ int T=queue[++head]; PtrToAdjVNode N=G->GraphList[T].FirstAdjV; for(;N;N=N->Next){ if(visited[N->AdjV]==0){ visited[N->AdjV]=1; printf(" %d",N->AdjV); queue[++rear]=N->AdjV; } } } } }

    ListComponent:列出连通集同时控制输出格式

    void ListComponent(LGraph G,void (*Function)(LGraph,int) ) { int i=0; for(i=0;i<G->vertexNumber;i++){ if(visited[i]==1)continue; printf("{"); Function(G,i); printf(" }\n"); } }
    Processed: 0.009, SQL: 9