zoukankan      html  css  js  c++  java
  • 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 }
    

    解题思路

    首先选择用什么方式表示图,邻接矩阵还是邻接表。根据题意:按编号递增的顺序访问邻接点,如果用邻接表的话插入的时候就很麻烦,因为需要额外的判断来保证递增顺序,所以我选择了用邻接矩阵表示图。那么可以先根据输入构建邻接矩阵,然后再对矩阵DFS和BFS。对于DFS,每遇到一个未访问邻接点就递归;对于BFS,和二叉树的层次遍历类似,借助于队列实现,每遇到一个未访问邻接点就入队。

    代码

    #include <stdio.h>
    #include <stdlib.h>
    
    #define MAXSIZE 10
    
    struct Graph {
        int vertexCount;    //顶点数
        int edgeCount;      //边数
        int matrix[MAXSIZE][MAXSIZE];   //用邻接矩阵表示图
    };
    typedef struct Graph *MGraph;
    
    //用链表表示队列
    struct QNode {
        int data;
        struct QNode *next;
    };
    typedef struct QNode *Queue;
    
    int visited[MAXSIZE] = {0};     //判断结点是否访问过
    
    MGraph createGraph(int N, int M);
    void listConnectedSet_DFS(MGraph graph);
    void listConnectedSet_BFS(MGraph graph);
    void DFS(MGraph graph, int index);
    void BFS(MGraph graph, int index);
    Queue createQueue();
    void pushQueue(Queue queue, int index);
    int popQueue(Queue queue);
    int isEmpty(Queue queue);
    
    int main() {
        int N, M;
        scanf("%d %d", &N, &M);
        MGraph graph = createGraph(N, M);
        listConnectedSet_DFS(graph);
        for (int i = 0; i < N; i++) {   //重置访问数组
            visited[i] = 0;
        }
        listConnectedSet_BFS(graph);
        return 0;
    }
    
    //创建无向图
    MGraph createGraph(int N, int M) {
        MGraph graph = (MGraph) malloc(sizeof(struct Graph));
        graph->vertexCount = N;
        graph->edgeCount = M;
        for (int i = 0; i < MAXSIZE; i++) {
            for (int j = 0; j < MAXSIZE; j++) {
                graph->matrix[i][j] = 0;
            }
        }
        for (int i = 0; i < M; i++) {
            int v1, v2;
            scanf("%d %d", &v1, &v2);
            graph->matrix[v1][v2] = 1;
            graph->matrix[v2][v1] = 1;
        }
        return graph;
    }
    
    //对整个图DFS
    void listConnectedSet_DFS(MGraph graph) {
        for (int i = 0; i < graph->vertexCount; i++) {
            if (!visited[i]) {
                printf("{");
                DFS(graph, i);
                printf(" }
    ");
            }
        }
    }
    
    //对整个图BFS
    void listConnectedSet_BFS(MGraph graph) {
        for (int i = 0; i < graph->vertexCount; i++) {
            if (!visited[i]) {
                printf("{");
                BFS(graph, i);
                printf(" }
    ");
            }
        }
    }
    
    //对一个连通集DFS
    void DFS(MGraph graph, int index) {
        visited[index] = 1;
        printf(" %d", index);
        for (int i = 0; i < graph->vertexCount; i++) {
            if (graph->matrix[index][i] == 1 && !visited[i]) {
                DFS(graph, i);
            }
        }
    }
    
    //对一个连通集BFS
    void BFS(MGraph graph, int index) {
        Queue queue = createQueue();
        pushQueue(queue, index);
        visited[index] = 1;
        printf(" %d", index);
        while (!isEmpty(queue)) {
            int index = popQueue(queue);
            for (int i = 0; i < graph->vertexCount; i++) {
                if (graph->matrix[index][i] == 1 && !visited[i]) {
                    pushQueue(queue, i);
                    printf(" %d", i);
                    visited[i] = 1;
                }
            }
        }
    }
    
    //新建队列,返回哨兵结点
    Queue createQueue() {
        Queue queue = (Queue) malloc(sizeof(struct QNode));
        queue->data = -1; queue->next = NULL;
        return queue;
    }
    
    //尾插法入队
    void pushQueue(Queue queue, int index) {
        Queue rear = queue;
        while (rear->next) rear = rear->next;
        Queue node = (Queue) malloc(sizeof(struct QNode));
        node->data = index; node->next = NULL;
        rear->next = node;
    }
    
    //删除首结点
    int popQueue(Queue queue) {
        if (!queue->next) return -1;
        Queue target = queue->next;
        int ret = target->data;
        queue->next = target->next;
        free(target);
        return ret;
    }
    
    //判断队列是否为空
    int isEmpty(Queue queue) {
        return queue->next == NULL;
    }
    
  • 相关阅读:
    python各种类型转换-int,str,char,float,ord,hex,oct等
    pandas快速入门
    python里面,将多个list列表合并成一个list列表
    对字符串进行切分的技巧
    Ubuntu 16.04 安装navicat (tar.gz)
    ubuntu 16.04 如何升级系统的scrapy旧版本(1.0.3)到最新版本
    ubuntu下,敲命令scrapy出现:0: UserWarning: You do not have a working installation of the service_identity module: 'cannot import name 'opentype''. Please install it from <https://pypi.python.org/pypi/servic
    Ubuntu下解压缩zip,tar,tar.gz,tar.bz2格式的文件
    简单的查看进程信息
    python正则表达式
  • 原文地址:https://www.cnblogs.com/AndyHY-Notes/p/12580317.html
Copyright © 2011-2022 走看看