06-图1 列出连通集 (25分)

本文介绍了一种使用深度优先搜索(DFS)和广度优先搜索(BFS)算法来遍历无向图中所有连通集的方法。通过具体实例展示了如何从编号最小的顶点出发,按递增顺序访问邻接点,最终列出所有连通集。

给定一个有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 }
/* 
    Name:06-图1 列出连通集 (25分)
    Copyright:
    Author: Ambition
    Date: <08/12/19 21:28>
    Description:
*/
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cmath>
#include <vector>
#include <cstring>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <algorithm>
using namespace std;
typedef long long ll;
#define INF 1<<30
#define MaxVertexNum 100			// 顶点数目的最大值
typedef int VertexType;				// 顶点的数据类型
typedef int EdgeType;				// 带权图边上的权值数据类型
typedef int InfoType;				// 边的信息,如权值 
typedef int ElemType;				// 元素类型 
bool visited[MaxVertexNum];			// 顶点访问标记数组 
struct ArcNode{						// 边表结点
	int adjvex;						// 该弧所指向的顶点的位置
	ArcNode* next;					// 指向下一条弧的指针
//	InfoType info;					// 网的边权值
};

struct MGraph{						// 定义邻接矩阵
	VertexType Vex[MaxVertexNum];	// 顶点表
	EdgeType Edge[MaxVertexNum][MaxVertexNum];	// 邻接矩阵,边表
	int vexnum, arcnum;				// 图当前顶点和弧数
};

typedef struct VNode{				// 顶点表结点
	VertexType data;				// 顶点信息
	ArcNode* first;					// 指向第一条依附该顶点的指针
} VNode, AdjList[MaxVertexNum];

struct ALGraph{						
	AdjList vertices;				// 邻接表 
	int vexnum, arcnum;				// 图的顶点数量和边的数量 
};	
 void CreatALGraphAndMGraph(ALGraph &ALG, MGraph &MG); 
 void PrintG(MGraph MG);
 void PrintG(ALGraph ALG);
 void visit(ALGraph &G, int v);
 void visit(MGraph  &G, int v);
 void DFS(ALGraph G, int v);
 void DFS(MGraph G, int v) ;
 void DFSTraverse(ALGraph G);
 void DFSTraverse(MGraph G) ;
 //void BFS(MGraph G);
 void CreatALGraphAndMGraph(ALGraph &ALG, MGraph &MG);
 void InsertArc(ALGraph &ALG,int v,int w);
 int countConnectedByBFS(MGraph &G) ;
 int countConnectedByBFS(ALGraph &G);
int main(int argc, char** argv) {
	//freopen("in.txt", "r", stdin);
    //freopen("out.txt", "w", stdout);
    int i,v,w;
    ALGraph ALG;//邻接表 
    MGraph MG;// 
	CreatALGraphAndMGraph(ALG,MG);
	//PrintG(ALG);
    DFSTraverse(ALG);
    countConnectedByBFS(ALG);
	return 0;
}
void PrintG(MGraph MG){
	int i,j,n;
	n=MG.vexnum;
	for(i=0; i<n; i++){
		for(j=0; j<n; j++){
			printf(" %d",MG.Edge[i][j]);
		}
		printf("\n");
	}
	for(i=0;i<n;i++){
		printf("V[%d]:%d ",i,visited[i]);
	}
	printf("\n");
}

void PrintG(ALGraph ALG){
	int i,j,n;
	n=ALG.vexnum;
	for(i=0; i<n; i++){
		printf("V[%d]=%d ",i,ALG.vertices[i].data);
		ArcNode *p=ALG.vertices[i].first;
		for(; p!=NULL; p=p->next){
			printf(" ->%d ",p->adjvex);
		}
		printf("\n");
	}
	
}

void visit(ALGraph &G, int v) {
	printf(" %d", G.vertices[v].data);
} 
void visit(MGraph  &G, int v) {
	printf(" %d", G.Vex[v]);
} 


void DFS(ALGraph G, int v) {
// 从顶点v出发递归的深度优先遍历图G(包含v的连通块)
	visited[v] = true;			// 标记顶点v访问 
	visit(G, v);				// 访问顶点v 
	for(ArcNode* p = G.vertices[v].first; p!=NULL; p=p->next) {		// 对顶点v尚未访问的邻接顶点p递归调用DFS 
		if(!visited[p->adjvex]) {
			DFS(G, p->adjvex);
		}
	}
}
void DFS(MGraph G, int v) {
// 从顶点v出发递归的深度优先遍历图G(包含v的连通块)
	visited[v] = true;			// 标记顶点v访问 
	visit(G, v);				// 访问顶点v 
	for(int w=0; w<G.vexnum; w++) {		// 对顶点v尚未访问的邻接顶点w递归调用DFS 
		if(G.Edge[v][w]>0&&!visited[w]) {
			DFS(G,w);
		}
	}
}
void DFSTraverse(ALGraph G) {
	for(int i=0; i<G.vexnum; i++) 
		visited[i] = false;	// 标记所有顶点为没有访问 
	for(int i=0; i<G.vexnum; i++) {				// 对所有没有访问的顶点i调用DFS访问该顶点所在连通块 
		if(!visited[i]) {
			printf("{");
			DFS(G, i);		
			printf(" }\n");
		}
	}
} 
void DFSTraverse(MGraph G) {
	for(int i=0; i<G.vexnum; i++) 
		visited[i] = false;	// 标记所有顶点为没有访问 
	for(int i=0; i<G.vexnum; i++) {				// 对所有没有访问的顶点i调用DFS访问该顶点所在连通块 
		if(!visited[i]) {
			printf("{");
			DFS(G, i);
			printf(" }\n");
			//PrintG(G);
		}
	}
}
int countConnectedByBFS(ALGraph &G){
	int i,v;
	for(v=0; v<G.vexnum; v++) visited[v]=false;
	queue<int> Q;  int cnt=0;
	for(v=0; v<G.vexnum; v++){
		if(!visited[v]){
			cnt++;
			printf("{");
			visited[v]=true;
			visit(G,v);
			Q.push(v);
			while(!Q.empty()){
				int w=Q.front();
				Q.pop();
				ArcNode *p=G.vertices[w].first;
				for( ; p!=NULL; p=p->next){
					if(!visited[p->adjvex]){
						visited[p->adjvex]=true;
						visit(G,p->adjvex);
						Q.push(p->adjvex);
					}
				}//for
			}//while
			printf(" }\n");
		}//if
	}//for
	return cnt; 
}//BFS

int countConnectedByBFS(MGraph &G) {
	for(int v=0; v<G.vexnum; v++) 					// 标记所有顶点为没有访问 
		visited[v] = false;
	queue<int> Q;									// 保存正在访问的结点队列
	int cnt = 0;									// 统计连通块数量 
	for(int v=0; v<G.vexnum; v++) {					// 遍历所有没有访问的结点 
		if(!visited[v]) {
			cnt++;									// 连通块数量增一 
			printf("{");
			visited[v] = true;						// 从当前结点开始BFS访问所在连通块的所有结点 
			//printf(" v=%d ",v);
			visit(G,v); 
			Q.push(v);								// 加入队列 
			while(!Q.empty()) {
				int w = Q.front();					// 弹出队首元素 
				Q.pop();
				for(int i=0; i<G.vexnum; i++) {		// 对顶点w尚未访问的邻接顶点i进行访问并入栈  
					if(G.Edge[w][i]>0 && !visited[i]) {
						visited[i] = true;
						visit(G,i);
						Q.push(i);
					}
				}
			}
			printf(" }\n");
			//PrintMG(G);
		}
	} 	
	return cnt; 
} 
void InsertArc(ALGraph &ALG,int v,int w){
	//向邻接表中插入一条<v,w>的边 
	ArcNode * s=(ArcNode *)malloc(sizeof(struct ArcNode)), *p;
	s->next=NULL; 
	s->adjvex=w; p=ALG.vertices[v].first;
	if(ALG.vertices[v].first==NULL||w<p->adjvex){//
		s->next=ALG.vertices[v].first;
		ALG.vertices[v].first=s; 
	} 
	else{
		int temp;
		while(p->next!=NULL&&w>p->adjvex) p=p->next; 
		if(p->next==NULL&&w>p->adjvex){
			p->next=s;
		}
		else{
			s->next=p->next;//先插入 
			p->next=s;
			temp=s->adjvex;//然后交换数据 
			s->adjvex=p->adjvex;
			p->adjvex=temp;
		}
	}
	//printf("insert <%d,%d>\n",v,w);
	//PrintG(ALG);
}
void CreatALGraphAndMGraph(ALGraph &ALG, MGraph &MG){
	int i,j,k,v,e;
 	scanf("%d%d",&v,&e); //输入顶点数v和边数e 
 	ALG.vexnum=v; ALG.arcnum=e;
 	MG.vexnum=v; MG.arcnum=e;
	for(i=0; i<v; i++){
		ALG.vertices[i].data=i;
		ALG.vertices[i].first=NULL;
		
		MG.Vex[i]=i;
	}
	for(k=0; k<e; k++){
		scanf("%d%d",&i,&j);
		InsertArc(ALG,i,j);
		InsertArc(ALG,j,i);
		
		MG.Edge[i][j]=MG.Edge[j][i]=1;
	} 
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值