一些概念
· 图由顶点(Vertex)和边(Edge)组成,每条边的两端都必须是图的两个顶点
· 图可分为有向图和无向图,无向图的边都是双向的,可以当作正负向两条边组成
· 顶点的度是指和该顶点相连的边的条数。对于有向图来说,顶点的出边条数称为该定点的出度,入边条数则为入度
· 顶点和边的量化属性称为权值,点权和边权
图的存储
1.邻接矩阵
另二维数组G[N][N]的两维分别表示图的顶点标号,如果顶点i和j之间有边且i->j,则另G[i][j]=1(也可存边权),若为无向边则另G[i][j]也为1(或边权),若不存在边则为0
注:邻接矩阵只适用于顶点数目不太大(一般≤1000)的情况
2.邻接表
用vector实现会比较方便:
vector<int> V[N]; //存顶点编号
若要添加一条从顶点i到顶点j的有向边:
V[i].push_bach(j);
也可以同时存顶点编号和边权,自行创建结构体即可:
struct Node{
int v,w;
};
则邻接表的定义更改为:
vector<Node> V[N];
添加从i到j的边权为x的有向边:
V[i].push_bach(Node{j,x});
图的遍历
几个概念
· 连通、连通图和连通分量
无向图中,如果从顶点i到j有路径,则称i与j连通,如果图中任意两个顶点之间都连通,则称该图为连通图;否则图中的极大连通子图称为连通分量。
· 强连通图和强连通分量
有向图中,若从i到j有路径,则称从i到j是连通的,如果对于每一顶点i和j,从i到j和从j到i都有路径,则称该图为强连通图;否则将其中的极大强连通子图称为强连通分量
(一般把连通分量和强连通分量统称为连通块)
1.深度优先搜索(DFS)遍历图
DFS伪代码如下:
DFS(u){ //访问顶点u
vis[u]=true; //设置u为已访问
for(从u出发能到达的所有顶点v)
if(vis[v]==false) //如果v未访问
DFS(v); //递归访问v ,此处访问深度+1
}
DFSTrave(G){ //遍历图G
for(G的所有顶点u)
if(vis[u]==false)
DFS(u); //访问u所在的连通块
//此处可一并操作数连通块个数
}
2.广度优先搜索(BFS)遍历图
BFS伪代码如下:
BFS(u){
queue q; //定义队列 <int>/<node>/...
将u入队;
vis[u]=true; //设置u为已访问
while(q非空){
取出q的队首元素u进行访问;
for(从u出发能到达的所有顶点v) //此处可更新层号
if(vis[v]==false){
将v入队;
vis[v]=true;
}
}
}
BFSTrave(G){
for(G的所有顶点u)
if(vis[u]==false)
BFS(u);
}
具体实现需根据题意合理建立邻接矩阵或邻接表,设置变量类型为int或结构体元素或其他~