Loading

<数据结构>XDOJ324,325图的优先遍历

XDOJ324.图的广度优先遍历

问题与解答

问题描述
已知无向图的邻接矩阵,以该矩阵为基础,给出广度优先搜索遍历序列,并且给出该无向图的连通分量的个数。在遍历时,当有多个点可选时,优先选择编号小的顶点。(即从顶点1开始进行遍历)
输入格式
第一行是1个正整数,为顶点个数n(n<100),顶点编号依次为1,2,…,n。后面是邻接矩阵,n行n列。
输出格式
共2行。第一行输出为无向图的广度优先搜索遍历序列,输出为顶点编号,顶点编号之间用空格隔开;第二行为无向图的连通分量的个数。
样例输入
6
0 1 0 0 0 0
1 0 0 0 1 0
0 0 0 1 0 0
0 0 1 0 0 0
0 1 0 0 0 1
0 0 0 0 1 0
样例输出
1 2 5 6 3 4
2

//图的广度优先遍历
#include<stdio.h>
#include<queue>
using namespace std;
#define MaxN 100
int G[MaxN][MaxN]; //邻接矩阵表示图
int inq[MaxN] = {false};  //标记数组
int connection = 0;  //连通分量
queue<int> que;  //队列声明
int n; //结点数

void BFSTrave();
void BFS(int u);

int main(){
    int i,j;
    //建立图
    scanf("%d", &n);
    for(i = 0; i < n; i ++){
        for(j = 0; j < n; j++){
            scanf("%d", &G[i][j]);
        }
    }
    //BFS输出结点及连通分量
    BFSTrave();
    printf("\n%d", connection);
}
void BFSTrave(){
    int u;
    for(u = 0; u < n; u++){
        if(inq[u] == false){  //若当前结点未被访问
            BFS(u);  //遍历其所在连通分量
            connection++; //连通分量数目+1
        }
    }
}
void BFS(int u){
    int v;
    que.push(u); //当前结点入队
    inq[u] = true;  //标记已访问
    printf("%d ", u+1);  //输出结点编号
    while(!que.empty()){
        u = que.front();
        que.pop();
        for(v = 0; v < n; v++){
            if(inq[v] == false && G[u][v] != 0){ //访问u未被访问过的邻接结点
                que.push(v);  //邻接结点入队
                inq[v] = true; //标记已访问
                printf("%d ", v+1); //输出结点编号
            }
        }
    }
}

XDOJ325.图的深度优先遍历

问题与描述

问题描述
已知无向图的邻接矩阵,以该矩阵为基础,给出深度优先搜索遍历序列,并且给出该无向图的连通分量的个数。在遍历时,当有多个点可选时,优先选择编号小的顶点。(即从顶点1开始进行遍历)
输入格式
第一行是1个正整数,为顶点个数n(n<100),顶点编号依次为1,2,…,n。后面是邻接矩阵,n行n列。
输出格式
共2行。第一行输出为无向图的深度优先搜索遍历序列,输出为顶点编号,顶点编号之间用空格隔开;第二行为无向图的连通分量的个数。
样例输入
6
0 1 0 0 0 0
1 0 0 0 1 0
0 0 0 1 0 0
0 0 1 0 0 0
0 1 0 0 0 1
0 0 0 0 1 0
样例输出
1 2 5 6 3 4
2

//图的深度优先遍历
#include<stdio.h>
#define MaxN 100
int G[MaxN][MaxN]; //邻接矩阵
int vis[MaxN] = {false}; // 标记矩阵
int connection = 0;  //连通分量
int n; //节点数
void DFS(int u);
void DFSTrave();
int main(){
    int num = 1;
    //建立图
    scanf("%d", &n);
    int i,j;
    for(i = 0; i < n; i++){
        for(j = 0; j < n; j++){
            scanf("%d",&G[i][j]);
        }
    }
    DFSTrave();
    printf("\n%d",connection);
}
void DFSTrave(){
    int u;
    for(u = 0; u < n; u++){ //遍历每一个顶点
        if(vis[u] == false){ // 未被访问
            DFS(u); //访问所在的连通分量
            connection++; // 连通分量+1
        }
    }
}
void DFS(int u){
    int v;
    vis[u] = true;  //设置该节点为已访问
    printf("%d ", u+1);
    for(v = 0; v < n; v++){
        if(vis[v] == false && G[u][v] != 0){  //遍历未被访问的邻接点
            DFS(v); //递归
        }
    }
}

题后反思

  1. BFS与DFS写法上:
    • 都需要建立标记数组vis[]/inq[]

    • 都有两个函数构成

      • BFS/BFSTrave(u)
      • DFS/DFSTrave(u)

      后者遍历u所在的连通分量

  2. queue的使用:先que.front()再que.pop()
posted @ 2021-12-16 23:16  咪啪魔女  阅读(312)  评论(0编辑  收藏  举报