7-7 列出连通集(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 } 这道题对于广搜部分就是一个简单的模板套用,没有什么不同,主要是深搜的标记普通的着路径的深搜是不同的,这里相当于遍历,每次每个点只能输出一次,但是一般的深搜 肯定会经过重复的点,所以这里标记后回溯的时候不再让它变成0,然后打印这个点,这样下次就不会走到这个点了
#include <iostream> #include <cstdio> #include <cstring> #include <queue> using namespace std; #define INF 0x3f3f3f3f int n,e; int mp[15][15]; int vis[15]; int haveprint[15]; void bfs(int s){ queue<int>q; int i; vis[s] = 1; q.push(s); while(!q.empty()){ int x = q.front(); printf("%d ",x); q.pop(); for(i = 0; i < n; i++){ if(mp[x][i]==1&&!vis[i]){ vis[i] = 1; q.push(i); } } } } void dfs(int s){ int i; printf("%d ",s); for(i = 0; i < n; i++){ if(mp[s][i]==1&&!vis[i]){ vis[i] = 1;//标记 dfs(i);//不再变成零 } } } int main(){ memset(mp,INF,sizeof(mp)); scanf("%d%d",&n,&e); int i; for(i = 0; i < e; i++){ int u,v; scanf("%d%d",&u,&v); mp[u][v] = 1; mp[v][u] = 1; } int j; //dfs memset(vis,0,sizeof(vis)); //memset(haveprint,0,sizeof(haveprint)); for(i = 0; i < n; i++){ if(!vis[i]){ vis[i] = 1; printf("{ "); dfs(i); printf("}\n"); } } //printf("---------------------------------------------\n"); //bfs memset(vis,0,sizeof(vis)); for(i = 0; i < n; i++){ if(!vis[i]){ printf("{ "); bfs(i); printf("}\n"); } } return 0; }