代码随想录|图论|01图论基础

发布于:2025-06-26 ⋅ 阅读:(19) ⋅ 点赞:(0)

比较详细的简介看下面这个链接:

图论理论基础 | 代码随想录

这里详细说几个自己不熟的结构:

度的概念

无向图:几条边连接这个节点,这个节点的度就是多少。

有向图:根据连接这个节点的线,指向箭头的是入度,指出箭头的是出度。

有向图是拓扑排序的基本。

连通图

是不是连通图就是任意两个节点是不是可以连起来的,有向图的话需要双向彼此都可以到达。

怎么构造图?

邻接矩阵和邻接表

1、邻接矩阵

用二维数组来表示图结构,从节点的角度出发。

比如grid[2][5] = 6,表示2指向5,权值为6;

比如grid[2][5] = 6,grid[5][2] = 6,表示无向图,权值为6;

一般有n的节点的情况下,需要设置一个    n+1*n+1     大小的邻接矩阵matrix,因为直接用节点数字表示索引比较方便。

这种表达方式在节点多、边少的情况下,会申请过大的二维数组,造成空间浪费,所以说适合稠密图,不适合稀疏图。

2、邻接表

邻接表是“数组+链表”的形式,从边出发,对于每个节点来说,有多少条边,就申请多长的链表。

如下图所示,5个节点,每个节点指向的边构成一个链表。

这里表达的图是:

  • 节点1 指向 节点3 和 节点5
  • 节点2 指向 节点4、节点3、节点5
  • 节点3 指向 节点4
  • 节点4指向节点1

下面通过一道题,来用ACM格式创建邻接矩阵和邻接表。

/*
通过邻接矩阵和邻接表两种方式构建有向图。
判断这两图是否完全相同,即每个顶点的邻居集合是否一致。
思路:
1、把邻接矩阵A转换成邻接表A
2、读入邻接表B
3、把邻接表A,B的每个节点的每个邻接表进行排序,方便等会比较
4、依次比较A,B的每个节点的邻接表
*/

#include <bits/stdc++.h>
using namespace std;

int main()
{
    int n;
    cin >> n;
    // 虽然邻接表是链表,可以用vector<list<int>>表示,但是这里写成二维矩阵是为了操作方便,用push_back末尾添加元素
    vector<vector<int>> adjA(n + 1);
    vector<vector<int>> adjB(n + 1);
    // 根据A的邻接矩阵输入,构建邻接表A
    for (int i = 1; i <= n; i++)
    {
        for (int j = 1; j <= n; j++)
        {
            int val;
            cin >> val;
            if (val == 1)
                adjA[i].push_back(j); // 这里j代表节点
        }
    }
    // 读取邻接表B
    for (int i = 0; i < n; i++)
    {
        int node, k;
        cin >> node >> k;
        // k只是数量,用来控制for循环
        for (int j = 0; j < k; j++)
        {
            int val;
            cin >> val;
            adjB[node].push_back(val); // 这里node表示起点节点,val代表终点节点
        }
    }
    // 现在两个邻接表的行是按照1~n的顺序排布的,所以对每一行内部进行排序
    for (int i = 1; i <= n; i++)
    {
        sort(adjA[i].begin(), adjA[i].end());
        sort(adjB[i].begin(), adjB[i].end());
    }
    // 比较邻接表,逐行比较,他们应该是每一行都相等
    bool isSame = true;
    for (int i = 0; i <= n; i++)
    {
        if (adjA[i] != adjB[i])
        {
            isSame = false;
            break;
        }
    }
    cout << (isSame ? "YES" : "NO") << endl;
    return 0;
}


网站公告

今日签到

点亮在社区的每一天
去签到