无向图的连通集
题目来源 :https://pintia.cn/problem-sets/15/problems/714
浙大pta
- 由于此图是无向图,所以在查找连通集合的时候,只要通过起始点进行深度优先搜索,或者广度优先搜索能够到达的点,就能够加入到连通集中去。
bfs 和 dfs
dfs
dfs是通过递归的形式对无向图进行遍历,由于递归运用了栈,所以每次都能回退到起始节点再进行
下一条路径的遍历。
void dfs(int i, int n){
printf(" %d",i);
vistag[i] = 1;
//从起始节点对每一条路径进行遍历
for (int j = 0; j < n; j++){
if (vistag[j] == 0 && map[i][j]){
dfs(j, n);
}
}
}
bfs
bfs不需要用到递归,他是按层次对起始点能够到达的点进行遍历,利用队列把起始节点的每一个相邻的节点
加入到连通集当中去。
void bfs(int i, int n){
vistag[i] = 1;
//先把起始节点push到队列中
que.push(i);
while (que.empty() == false){
//每次都拿队头节点,并且对他的相邻节点map[vis][j]进行visit
int vis = que.front();
printf(" %d",vis);
que.pop();
for (int j = 0; j < n; j++){
if (vistag[j] == 0 && map[vis][j]){
vistag[j] = 1;
que.push(j);
}
}
}
}
全部代码
#include<cstdio>
#include<queue>
#include<string.h>
using namespace std;
queue<int>que;
int vistag[100] = { 0 };
int map[100][100] = { 0 };
void dfs(int i, int n){
printf(" %d",i);
vistag[i] = 1;
for (int j = 0; j < n; j++){
if (vistag[j] == 0 && map[i][j]){
dfs(j, n);
}
}
}
void bfs(int i, int n){
vistag[i] = 1;
que.push(i);
while (que.empty() == false){
int vis = que.front();
printf(" %d",vis);
que.pop();
for (int j = 0; j < n; j++){
if (vistag[j] == 0 && map[vis][j]){
vistag[j] = 1;
que.push(j);
}
}
}
}
int main(){
int N, E;
int v, u;
while (scanf("%d%d", &N, &E) != EOF){
memset(vistag, 0, sizeof(vistag));
memset(map, 0, sizeof(map));
for (int i = 0; i < E; i++){
scanf("%d%d", &v, &u);
map[v][u] = 1;
map[u][v] = 1;
}
for (int i = 0; i < N; i++){
if (vistag[i] == 0){
printf("{");
dfs(i, N);
printf(" }\n");
}
}
memset(vistag, 0, sizeof(vistag));
for (int i = 0; i < N; i++){
if (vistag[i] == 0){
printf("{");
bfs(i, N);
printf(" }\n");
}
}
}
return 0;
}