图论基础
前言:
本篇文章将会讲解图论所有基本知识,不会涉及算法,可以放心食用。
可能不是很标准,望大家见谅
一、图论基本概念:
图论(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});
}
}

浙公网安备 33010602011771号