Resumen de aprendizaje del algoritmo de Dijkstra

1. Realizar con matriz de adyacencia (para ser llenado...)

2. Realizar con lista de adyacencia

definición de lista de adyacencia

#define MaxVertexnum 100 //最大顶点数量
int dis[MaxVertexnum] = { 0 }; //单源最短路径
bool vis[MaxVertexnum] = { 0 }; //访问标志位
#define INF 0x7fffffff //最大值
#define VertexType int //顶点类型
#define InfoType int //边权重类型

typedef struct ArcNode{
    int adjvex; //边指向结点
	InfoType info; //边权重
	struct ArcNode* next;
};

typedef struct VNode {
	VertexType name;
	ArcNode* first;
}AdjList[MaxVertexnum];

typedef struct {
	AdjList node;
	int vexnum;
	int arcnum;
}ALGraph;

Comprensión concreta, un total de tres estructuras están conectadas entre sí, lo que se puede comparar con la representación del hermano menor y la clasificación radix del árbol y el método de la cremallera de la tabla hash. Los tres tienen el mismo efecto.

 dijkstra logra

  1. Primero encuentre el punto no visitado u con la distancia más pequeña en la lista actual de dis [] distancia
  2. Si no se encuentra, significa que se ha calculado la distancia más corta de todos los puntos
  3. Si lo encuentra, elimine todos los puntos adyacentes de u, calcule y actualice la distancia más corta
  4. Vuelva al paso (1) y continúe hasta completar la operación
void dijkstra(ALGraph* G, int start) {
	fill(vis, vis + MaxVertexnum, 0); //访问标志初始化
	fill(dis, dis + MaxVertexnum, INF); //路径初始化
	dis[start] = 0; //源点到自己的距离为0
	int i, j, u, min;
	for (i = 0; i < G->vexnum; i++) {
		u = -1; //在未被访问过的顶点中找到距离最短的点
		min = INF;
		for (j = 1; j <= G->vexnum; j++) {  
			if (vis[j] = false && dis[j] < min) {
				u = j; 
				min = dis[j];
			}
		}
		if (u == -1) return; //所有顶点均已访问
		vis[u] = true;
		ArcNode* tmp = G->node[u].first; //找到距离最短的顶点u的邻接点
		printf("\n\n\n");
		while (tmp) {
			//若该邻接点未被访问过 且 源点到u的最短距离+u到该邻接点的距离小于该邻接点此前的最短距离
			if (vis[tmp->adjvex] == false && dis[u] + tmp->info < dis[tmp->adjvex]) 
				dis[tmp->adjvex] = dis[u] + tmp->info;
			tmp = tmp->next; //继续访问u的下一个邻接点
		}
	}

}

 3. Implementación abstracta de la plantilla del algoritmo de Dijkstra (para preguntas)

#include <bits/stdc++.h>
using namespace std;
struct node {
	int id, dis;
	bool friend operator < (const node& a, const node& b) {
		return a.dis > b.dis;
	}
};
int n, m, s;
int ui, vi, wi;
vector<pair<int, int>> E[100];
int dis[100];
int vis[100];
void dijkstra() {
	fill(dis, dis + 100, 1e9); //初始化dis列表
	dis[s] = 0;
	priority_queue<node> Q;
	Q.push(node{ s, 0 });
	while (!Q.empty()) {
		int Now = Q.top().id; //当前Now顶点的距离最短
		int D = Q.top().dis; //D为Now顶点目前的最短距离
		Q.pop();
		//对应底下①语句,因每次更新数据都会把距离放进列表,故当计算完所有距离后依旧留下一堆无用数据,用此语句进行过滤
		if (vis[Now]) continue; 
		vis[Now] = 1;
		for (auto it : E[Now]) { //访问Now的所有邻边
			int des = it.first;
			int weigh = it.second;
			if (dis[des] > D + weigh) { //源点到Now的距离+Now到des的距离 < 先前des的最短距离
				dis[des] = D + weigh;
				Q.push(node{ des, dis[des] }); //①
			}
		}
	}
}
int main() {
	cin >> n >> m >> s; //n:顶点数	m:边数,s:源点
	for (int i = 0; i < m; i++) {
		cin >> ui >> vi >> wi; //从ui到vi权重为wi的一条边
		E[ui].push_back({ vi,wi });
	}
	dijkstra();
	for (int i = 1; i <= n; i++) {
		printf("%d ", dis[i]);
	}

	return 0;
}

 La plantilla se puede entender concretamente por la siguiente figura

 Si desea obtener esta imagen, debe ingresar los datos de esta manera y comparar los datos de entrada con la estructura abstracta a la derecha de la imagen de arriba, y puede encontrar la conexión interna

5 8 0
0 1 1
0 2 2
0 4 1
2 1 3
2 3 2
2 4 2
3 4 1
3 1 2

Muestras de entrada y salida

 entrada #1

4 6 1
1 2 2
2 3 2
2 4 1
1 3 5
3 4 3
1 4 4

Salida #1

0 2 4 3

4. Algoritmo de Floyd

Añadir un algoritmo de Floyd como complemento

int n;
int A[100][100], path[100][100];
void floyd() {
	fill(path, path + 10000, -1); //初始化path数组为-1
	for (int k = 0; k < n; k++) { //考虑以Vk作为中转点
		for (int i = 0; i < n; i++) { //遍历整个矩阵,i为行号,j为列号
			for (int j = 0; j < n; j++) { 
				if (A[i][j] > A[i][k] + A[k][j]) { //以Vk为中转点的路径更短
					A[i][j] = A[i][k] + A[k][j]; //更新最短路径长度
					path[i][j] = k; //中转点
				}
			}
		}
	}
}

Supongo que te gusta

Origin blog.csdn.net/qq_21891843/article/details/126324602
Recomendado
Clasificación