Dijkstra算法
迪杰斯特拉算法用来解决单源最短路问题,即给的图G和起点s,通过算法得到s到达其他每个顶点的最短距离
概念
基本思想:对图G(V,E)
设置集合S,存放已被访问顶点,然后每次从集合V - S
中选择与起点s的最短距离最小的一个顶点(记为u),访问并加入集合S。之后,令顶点u为中介点,优化起点s与所有从u能到达的顶点v之间的最短距离,操作n次(n为顶点数),直到集合S包含所有顶点
例子
邻接矩阵
#include<cstdio>
const int MAXV = 1000;
const int INF = 100000000;
int n, G[MAXV][MAXV];
int dist[MAXV];
bool vis[MAXV] = {false};
void Dijkstra(int s){
fill(dist, dist + MAXV, INF);
dist[s] = 0;
for(int i = 0; i < n; i++){
int u = -1, MIN = INF;
for(int j = 0; j < n; j++){
if(vis[j] == false && dist[j] < MIN){
u = j;
MIN = dist[u];
}
}
if(u == -1) return;
vis[u] = true;
for(int v = 0; v < n; v++){
if(vis[v] == false && G[u][v] != INF && dist[u] + G[u][v] < dist[v]){
dist[v] = dist[u] + G[u][v];
}
}
}
}
邻接表
#include<cstdio>
#include<vector>
using namespace std;
const int MAXV = 1000;
const int INF = 100000000;
struct node{
int v, dist; // v为边的目标顶点,dis为边权
};
int n;
vector<node> Adj[MAXV];
int dist[MAXV];
bool vis[MAXV] = {false};
void Dijkstra(int s){
fill(dist, dist + MAXV, INF);
dist[s] = 0;
for(int i = 0; i < n; i++){
int u = -1, MIN = INF;
for(int j = 0; j < n; j++){
if(vis[j] == false && dist[j] < MIN){
u = j;
MIN = dist[j];
}
}
if(u == -1) return;
vis[u] = true;
for(int j = 0; j < Adj[u].size(); j++){
int v = Adj[u][j].v;
if(vis[v] == false && dist[u] + Adj[u][j].dist < dist[v]){
dist[v] = dist[u] + Adj[u][j].dist;
}
}
}
}
以上所计算的是最短路径,为了计算得到最短路径,设置pre[]
数组,令pre[v]
表示从起点s到顶点v的最短路径上v的前一个顶点(即前驱结点)的编号
#include<cstdio>
const int MAXV = 1000;
const int INF = 100000000;
int n, G[MAXV][MAXV];
int dist[MAXV];
int pre[MAXV];
bool vis[MAXV] = {false};
void Dijkstra(int s){
fill(dist, dist + MAXV, INF);
dist[s] = 0;
for(int i = 0; i < n; i++){
int u = -1, MIN = INF;
for(int j = 0; j < n; j++){
if(vis[j] == false && dist[j] < MIN){
u = j;
MIN = dist[u];
}
}
if(u == -1) return;
vis[u] = true;
for(int v = 0; v < n; v++){
if(vis[v] == false && G[u][v] != INF && dist[u] + G[u][v] < dist[v]){
dist[v] = dist[u] + G[u][v];
pre[v] = u; // 记录v的前驱顶点是u(新添加)
}
}
}
}
之后,利用递归来求出整条路径:
void DFS(int s, int v){ // s为起点编号,v为当前访问的顶点编号
if(s == v){
printf("%d
", s);
return;
}
DFS(s, pre[v]);
printf("%d
", v);
}
三种常见题型
Write by Gqq