图的表示
- 邻接矩阵,适合稠密图
注意初始化时,自身可以用0表示,不相连的结点可以用负数、正无穷表示,具体要看不同应用的场景。相邻的结点,如果是无权图,可以用1表示;如果是有权图,可以用它们的的权重来表示。 - 邻接表,适合稀疏图
图的遍历
- DFS:深度优先
void DFS(结点V)
{
访问V
visited[V] = true;//标记为已访问
for(V的邻接每个结点W){
if(!visited[W]) DFS(W);
}
}
- BFS:广度优先
void BFS(结点V){
访问V
visited[V] = true;
queue.push(V);
while(!queue.empty()){
V = queue.front();
queue.pop();
for(V的每个邻接点W){
if(!visited[W]){
访问W;
visited[W] = true;
queue.push(W);
}
}
}
}
最短路径
- 无权图的单源最短路径。
直接利用BFS
dist[i] 表示从开始结点S到结点i的路径长度。dist[S] = 0,其余都初始化为-1
path[i]表是S到i路径上经过的某结点。
void unweightedShort(结点 S){
queue.push(S);
while(!queue.empty()){
结点V = queue.pop();
for(V的每个邻接点W){
if(dist[W] == -1){
dist[W] = dist[V] + 1;
path[W] = V;
queue.push(W);
}
}
}
}
- 有权图的单源最短路径
Dijkstra算法
void Dijkstra(结点 S){
collected[S] = 1;
while(1){
结点V = 未被收录的结点中dist最小者;
if(这样的V不存在) break;
collected[V] = 1;
for(所有V的邻接点W){
if(!collected[W]){
if(dist[V] + graph[W][V] <= dist[W]){
dist[W] = dist[V] + graph[W][V];
path[W] = V;
}
}
}
}
}
- 多源最短路径
方法一:将dijkstra算法调用n次。
方法二:floyd算法
D[i][j]表示i到j的路径长度
void Flody(Graph G){
for(int i=0; i<n; i++){
for(int j=0; j<n; j++){
D[i][j] = G[i][j]; //先初始化D[i][j]为图的邻接矩阵中的值。注意不相邻的顶点值为正无穷大
}
}
//注意k在最外层
for(int k=0; k<n; k++){
for(int i=0; i<n; i++){
for(int j=0; j<n; j++){
if(D[i][k] + D[k][j] < D[i][j])
D[i][j] = D[i][k] + D[k][j];//以k为中继结点更短时就更新最短路径。
}
}
}
}
Flody算法时间复杂度时O(N^3)。