图论基础

前言:

本篇文章将会讲解图论所有基本知识,不会涉及算法,可以放心食用。

可能不是很标准,望大家见谅


一、图论基本概念:

图论(Graph Theory)是数学的一个分支。它以图为研究对象。图论中的图是由若干给定的点及连接两点的线所构成的图形,这种图形通常用来描述某些事物之间的某种特定关系,用点代表事物,用连接两点的线表示相应两个事物间具有这种关系。

如果想看更多更专业的概念,可以参考[oi-wiki](图论相关概念 - OI Wiki)

1、点:

点是构成图的基本元素,每个点一般会拥有一个数值,我们可以将该数值成为点权,即点的权重

2、边:

边是用于连接两个点的线段,通常来说,边有两种形式,一种是有向边,一种是无向边

有向边指这条边有一个特定的方向,具有指向性,并且要注意,在两个点中如果边的方向不一致,则这两条边不为同一条边

4、分类:

稀疏图:稀疏图指该图中的边的数量小于 \(n log n\)\(n\)指代点的数量)

稠密图:稠密图指该图中的边的数量大于 \(n log n\)

完全图:若该图中任何一对点都有边相连,则称该图为完全图。若图中的边为有向边,则改图也可以称为有向完全图,反之即是无向完全图

有向图&无向图:有向图指图中的边都是有向边,反之即是无向图

连通图:如果以任意一个点为起点,在图上沿着边走都可以到达其他所有点(有向图必须沿有向边的方向),那么这个图就是连通图

5、度:

无向图中,顶点的是指某个顶点连出的边数。

在有向图中,和度对应的是入度出度这两个概念。顶点的入度是指以该顶点为终点的有向边数量;顶点的出度是指以顶点为起点的有向边数量。需要注意的是,在有向图里,顶点是没有的概念的。

6、环:

有向图中,若一个点能够通过其它边回到自己,则此时就出现了一条环路


二、存图方式:

1、邻接矩阵:

邻接矩阵使用二维数组来存图的信息。

示例代码:

int n,m;//n表示点的数量,m表示边的数量
int g[101][101];//存图数组
int main(){
    cin>>n>>m;
    for(int i=1;i<=m;i++){
        int u,v,w;//u,v代表一条边的起始坐标与终点坐标,w代表该边权重
        cin>>u>>v>>w;
        g[u][v]=w;//这里可以抽象理解为u-v之间有一条权重为w的边,但注意这是单向的只能代表从u到v有一条边
	}
}

该方法的优点是查找效率高,代码简单,易于理解;缺点是空间占用太大,不适用于稀疏图

2、链式前向星

链式前向星是一种优秀的存图方式,大大节省了空间,但代价是换取了少量的时间

其本质是利用链表的思想

示例代码:

// head[u] 和 cnt 的初始值都为 -1
void add(int u, int v) {
  nxt[++cnt] = head[u];  // 当前边的后继
  head[u] = cnt;         // 起点 u 的第一条边
  to[cnt] = v;           // 当前边的终点
}

// 遍历 u 的出边
for (int i = head[u]; ~i; i = nxt[i]) {  // ~i 表示 i != -1
  int v = to[i];
}

3、邻接表:

邻接表是对于邻接矩阵的一种优化,于链式前向星高度相似,但代码更为简单

本质用了动态数组\(vector\)进行了优化

示例代码(不带边权):

int n,m;//n表示点的数量,m表示边的数量
vector<int> g[101];//存图数组
int main(){
    cin>>n>>m;
    for(int i=1;i<=m;i++){
        int u,v;//u,v代表一条边的起始坐标与终点坐标
        cin>>u>>v;
        g[u].push_back(v);
	}
}

示例代码(带边权):

int n,m;
vector<pair<int,int>> g[101];//存图数组
int main(){
    cin>>n>>m;
    for(int i=1;i<=m;i++){
        int u,v,w;
        cin>>u>>v>>w;
        g[u].push_back({v,w});
	}
}
posted @ 2025-03-16 16:10  AC-wyr  阅读(232)  评论(0)    收藏  举报