• 判断无向图是否联通模板(并查集版)(DFS),BFS等其他方法将陆续更新


    所谓并查集一般是两个功能,当然其他的拓展一下即可

    功能一,并,就是指把两颗树并在一起

    功能二,查,就是查找这个节点的根节点(根节点的根节点就是本身)

    emmmm对于判断我们不需要用到并的功能,因为,,,都并到一起了,还分个球的不通

    /*
    这种解法是因为若一个无向图是联通的那么任意两个点就是连着的
    则可以把他们看成一棵树,只是看成而已,因为会有环
    如果都是联通的,那么则会只有一个根,如果有多个根则说明不是联通图
    */
    #include"pch.h"
    #include<stdio.h>
    #include<iostream>
    #include <queue>
    #include<cmath>
    #define mem(a,b) memset(a,b,sizeof a);
    #define INF 0x3f3f3f3f
    using namespace std;
    typedef long long ll;
    const int maxn = 1010;
    int n, m;
    int pre[maxn];//存其根节点的序号
    //初始化,让其本身为其根
    void init()
    {
        for (int i = 1; i <= n; i++)
            pre[i] = i;
    }
    //寻找该节点的根节点
    int find(int x)
    {
        return pre[x] == x ? x : pre[x] = find(pre[x]);
    }
    
    int main()
    {
        while (~scanf_s("%d%d", &n, &m))
        {
            init();
            int u, v;
            for (int i = 0; i < m; i++)
            {
                scanf_s("%d%d", &u, &v);
                pre[find(u)] = pre[find(v)]; // 合并为同一个根
            }
    
            int cnt = 0;
            for (int i = 1; i <= n; i++) // 统计 root 结点个数
                if (pre[i] == i)
                {
                    cnt++;
                    if (cnt > 1) break;
                }
    
            puts(cnt == 1 ? "YES" : "NO");
        }
    
        return 0;
    }

     接下来是用DFS算法的解法

    首先我们了解一下什么是DFS

    深度优先搜索算法(英语:Depth-First-Search,简称DFS)是一种用于遍历或搜索树或图的算法。

    沿着树的深度遍历树的节点,尽可能深的搜索树的分支。当节点v的所在边都己被探寻过,搜索将回溯到发现节点v的那条边的起始节点。

    这一过程一直进行到已发现从源节点可达的所有节点为止。

    如果还存在未被发现的节点,则选择其中一个作为源节点并重复以上过程,

    整个进程反复进行直到所有节点都被访问为止。属于盲目搜索。

    简称不撞南墙不回头

    深度优先遍历的主要思想就是:首先以一个未被访问过的顶点作为起始顶点,沿当前顶点的边走到未访问过的顶点;

    当没有未访问过的顶点时,则回到上一个顶点,继续试探访问别的顶点,直到所有的顶点都被访问。
    沿着某条路径遍历直到末端,然后回溯,再沿着另一条进行同样的遍历,直到所有的顶点都被访问过为止。

    所以这里我们可以对每个顶点进行DFS,如果能一次遍历所有顶点则是联通的,反之则不是联通的

    /*
    DFS解法
    by tp
    */
    #include<cstdio>
    #include<cstring>
    using namespace std;
    const int maxn = 100;
    int p[maxn][maxn];//这里在数据范围小的时候使用邻接矩阵会简单方便很多
    int known[maxn];//这里是存放该节点是否被访问过的判断
    int v, e;//顶点数,遍数
    
    void DFS(int s)
    {
        for (int u = 0; u < v; u++)
        {
            if (!known[u] && p[s][u])//只有没访问过的且联通的点才进行访问
            {
                known[u] = 1;  //访问过的点进行标记
                DFS(u);
            }
        }
        return;
    }
    
    int main()
    {
        while (scanf("%d%d", &v, &e) != EOF)
        {
            memset(p, 0, sizeof(p));
            memset(known, 0, sizeof(known));
    
            int s, t;
            for (int i = 0; i < e; i++)
            {
                scanf("%d%d", &s, &t);
                p[s][t] = 1;
                p[t][s] = 1;
            }
            int count = 0;
            for (int i = 0; i < v; i++)
            {
                if (!known[i])
                {
                    DFS(i);
                    count++;
                }
            }
            if (count == 1)//如果是联通的图,那么在一次DFS在就会全标记上,所以count只会加一次
            {
                printf("是连通图
    ");
            }
            else {
                printf("不是连通图,count=%d
    ", count);
            }
        }
        return 0;
    }
  • 相关阅读:
    Ubuntu14.04手动安装配置jdk sdk ndk ant
    Ubuntu中(桌面或者文件夹)右键鼠标打开终端设置
    C语言中固定长度和不定长度的数组初始化示例
    Algorithm Design——最大公约数、最小公倍数
    Algorithm Design——凸包
    Algorithm Design——判断线段是否相交
    Algorithm Design Everyday——2.查找学生信息
    Algorithm Design——查找
    Algorithm Design——高精度整数四则运算
    Algorithm Design——并查集
  • 原文地址:https://www.cnblogs.com/tp25959/p/10815931.html
Copyright © 2020-2023  润新知