06-图1 列出连通集 (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 }
主要思路:
1、邻接矩阵存储图
2、深度优先遍历图与广度优先遍历图的方法
#include <iostream> #include <vector> #include <queue> using namespace std; #define MaxNode 10 typedef struct { int value[MaxNode][MaxNode]; int N; int M; }Graph; void DFS(vector<int> &flag,Graph &G,int node)//图的深度优先遍历 { flag[node]=1; cout<<" "<<node; for (int i=0; i<G.N; ++i) { if (G.value[node][i]==1 && flag[i]==0) { DFS(flag,G,i); } } } void BFS(vector<int> &flag,queue<int> &Q,Graph &G,int node)//图的广度优先遍历 { flag[node]=1; Q.push(node); int temp=0; while (!Q.empty()) { temp=Q.front(); cout<<" "<<temp; Q.pop(); for (int i=0; i<G.N; ++i) { if (G.value[temp][i]==1 && flag[i]==0) { Q.push(i); flag[i]=1; } } } } int main() { //Get the input int N=0,M=0; cin>>N>>M; Graph G; G.N=N; G.M=M; int x=0,y=0; for (int i=0; i<N; ++i)//初始化图的邻接矩阵 { for (int k=0; k<N; ++k) { G.value[i][k]=0; } } for (int i=0; i<M; ++i)//修改图的邻接矩阵 { cin>>x>>y; G.value[x][y]=1; G.value[y][x]=1; } //根据深度优先遍历输出图的联通集团 vector<int> flag(N,0);//结点是否被访问的标记向量 for (int i=0; i<N; ++i) { if (flag[i]==0) { cout<<"{"; DFS(flag,G,i); cout<<" }"<<endl; } } //根据广度优先遍历输出图的联通集团 vector<int> flag1(N,0);//结点是否被访问的标记向量 queue<int> Q; for (int i=0; i<N; ++i) { if (flag1[i]==0) { cout<<"{"; BFS(flag1,Q,G,i); cout<<" }"<<endl; } } }