列出连通集 (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 }
使用vector存储图,简单的深搜和广搜~~
也可以使用二维数组存储图~~
我在最后打印的时候,是将所有结果都存储在一个list的链表里,其中,我用-1和-2来间隔连通图,同时标志了 ' { '和 ' } '
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <vector>
#include <list>
using namespace std;
vector<int> g[10];
bool book[10];
int n,m;
list<int> l,q;
int dfs(int qi_ge_po_ming_zhen_nan){ ///词穷了...找不到合适的名字。其实就是图的顶点
l.push_back(qi_ge_po_ming_zhen_nan);
for(int i = 0; i < (int)g[qi_ge_po_ming_zhen_nan].size(); ++i){
if(!book[ g[qi_ge_po_ming_zhen_nan].at(i) ]){
book[ g[qi_ge_po_ming_zhen_nan].at(i) ] = true;
dfs(g[qi_ge_po_ming_zhen_nan].at(i));
}
}
return 0;
}
int bfs(){
memset(book,0,sizeof(book));
for(int i = 0; i < n; ++i){
if(!book[i]){
q.push_back(i);
l.push_back(i);
book[i] = true;
while(!q.empty()){
for(int j = 0; j < (int)g[q.front()].size(); ++j){
if(!book[ g[q.front()].at(j) ]){
q.push_back(g[q.front()].at(j));
l.push_back(g[q.front()].at(j));
book[ g[q.front()].at(j) ] = true;
}
}
q.pop_front();
}
l.push_back(-1);
l.push_back(-2);
}
}
return 0;
}
int main()
{
list<int>::iterator t;
cin>>n>>m;
memset(book,0,sizeof(book));
while(m--){ //构建邻接表
int x,y;
cin>>x>>y;
g[x].push_back(y);
g[y].push_back(x);
}
for(int i = 0; i < n; ++i)
sort(g[i].begin(),g[i].end());//因为是按序号从小到大输出和搜索,所以要对每个vector排下序~~
for(int i = 0; i < n; ++i){ //深搜
if(!book[i]){
book[i] = true;
dfs(i);
l.push_back(-1);
l.push_back(-2);
}
}
bfs(); //广搜
/*
for(t = l.begin(); t != l.end(); t++){
int temp = *t;
printf("%d ",temp);
}
cout<<endl;
*/
l.pop_back();
printf("{ ");
while(!l.empty()){ //输出
if(l.front() == -1) printf("}\n");
else if(l.front() == -2) printf("{ ");
else printf("%d ",l.front());
l.pop_front();
}
return 0;
}