图的深度、广度优先遍历讲义
1.基本概念
图可以理解成一个二元组,是由点集\(V\)和边集\(E\)组成的。
\(G=(V, E)\),\(V\)表示点的集合,\(E\)表示边的集合。
每条边是一幅点对\((v,w) v,w\)都是点集V中的点。\((v,w∈V)\)
图的分类:可以按照边有无方向,可以分为有向图和无向图。
无向图:每条边都是无向的图为无向图
有向图:每条边都是有向的图为有向图
图的分类:可以按照边的数量分为,简单图和多重图
简单图:在无向图中,任意2点间只有1条边;在有向图中,任意2点间只有1条同向边
多重图:在无向图中,任意2点间不只有1条边;在有向图中,任意2点间不只有有1条同向边
图的度
在无向图中,与这个结点相连的边的个数,称为结点的度。比如在图1中,\(X\)的度数为4
在有向图中,结点的度分为入度和出度。
结点的入度:以这个结点为终点的有向边的个数
结点的出度:以这个结点为起点的有向边的个数
比如在图2中,\(A\)的入度为0,出度为2
性质:\(图的总度数=边数*2\)
连通
无向图中:从任意点,都存在到达其它点的路径,称为连通图。
有向图中:从任意点,都存在到达其它点的路径,称该有向图是强连通的 。
子图
对于图\(G\)和图\(G’\),如果图\(G’\) 的边集和点集都是图\(G\)的边集和点集的子集,那么图\(G’\)是图\(G\)的子图
导出子图
对于图\(G\)和图\(G’\),如果图\(G’\)的点集都是图\(G\)点集的子集,那么图\(G’\)是图\(G\)的导出子图,其边集不一定是图\(G\)边集的子集。
补图
对于图\(G\)和图\(G’\),如果\(2\)个图的点集相同,边集没有交集,并且边集为完全图的边集,那么图\(G\)和图\(G’\) 互为补集。
其它概念
权值: 边的“费用”,可以看成是边的长度
回路: 起点和终点相同的路径,称为“回路”,或者“环”
完全图: 无向图中,如果任意两点之间都存在一条边,则是一个无向完全图,无向完全图有\(n*(n-1)/2\)条边;有向图中,如果任意两点之间都存在互通的两条边,则是一个有向完全图,有向完全图有\(n*(n-1)\)条边。
稠密图: 边数接近于完全图的图
稀疏图: 边数远远少于完全图的图
强连通分量: 有向图中任意两点都连通的最大子图。
2. 图的存储方式–邻接矩阵
int G[i][j]; //G[i][j]表示从点i到点j的权值,定义如下
| G[i][j] | 有边 | 没有边 |
|---|---|---|
| 有权图 | 权值 | ∞ |
| 无权图 | 1 | 0 |
3. 图的存储方式–邻接表
邻接矩阵存储的缺点在于,当图是稀疏图时,邻接矩阵的存储效率很低。为此,我们图有另外一种存储方式,邻接表。
无权图的邻接表存储
| 顶点 | 相邻的顶点的列表 |
|---|---|
| 0 | 1 |
| 1 | 3 |
| 2 | 1 |
| 3 | 0,2 |
| 4 | 3 |
vector<int> g[MAXN];
g[i].push_back(j);//i→j 存在有向边
//g[j].push_back(i); 如果是无向图,该代码也得加上。
#include <vector>
vector<int> G[5];
G[0].push_back(1);
G[1].push_back(3);
G[2].push_back(1);
G[3].push_back(0);
G[3].push_back(2);
G[4].push_back(3);
有权图的邻接表存储
因为除了需要存放点集之外,也要存放权值,此时定义结构体
struct edge{
int to;
int w;
}
vector<edge> g[MAXN];
g[i].push_back((edge){j,w});//i→j 存在有向边,权值为w
g[j].push_back((edge){i,w});//如果是无向图,该代码也得加上。
4. 图的深搜
邻接矩阵存储时,时间复杂度O(n^2),邻接表存储时,时间复杂度是O(n+m)
bool vis[MAXN];
bool G[MAXN][MAXN];
void dfs(int pos){
vis[pos]=true;
for(int i=1;i<=n;i++){
if(!G[pos][i]) continue;
if(vis[i]) continue;
dfs(i);
}
}
5. 图的广搜
邻接矩阵存储时,时间复杂度O(n^2),邻接表存储时,时间复杂度是O(n+m)
for(int pos=1;pos<=n;pos++){
if(vis[pos]) continue;
q.push(pos);
vis[pos]=true;
while(!q.empty()){
int u=q.front();
q.pop();
for(int i=0;i<g[u].size();i++){
int v=g[u][i];
if(!vis[v]) continue;
vis[v]=true;
q.push(v);
}
}
}
ICtiger's Blog
求关注
$e^{ix}=cosx+isinx$