https://blog.csdn.net/YF_Li123/article/details/74090301
Dijkstra算法伪代码:
//G为图;数组d为源点到达各点的最短路径长度,s为起点
Dijkstra(G, d[], s)
{
初始化;
for(循环n次)
{
u = 使d[u]最小的还未被访问的顶点的标号;
记u已被访问;
for(从u出发能到达的所有顶点v)
{
if(v未被访问 && 以u为中介点使s到顶点v的最短距离d[v]更优)
{
优化d[v];
}
}
}
}
邻接表:
const int INF = 1000000000;
struct Node
{
int v; //边的目标顶点
int dis; //dis为边权
Node(int x, int y) :v(x), dis(y) {}
};
void Dijkstra(int n, int s, vector<vector<Node>> Adj, vector<bool> vis, vector<int>& d)
{
/*
param
n: 顶点个数
s: 起点
Adj: 图的邻接表
vis: 标记顶点是否被访问
d: 存储起点s到其他顶点的最短距离
*/
fill(d.begin(), d.end(), INF);
d[s] = 0; //起点s到达自身的的距离为0
for (int i = 0; i < n; ++i)
{
int u = -1; //找到d[u]中最小的u
int MIN = INF; //找到最小的d[u]
for (int j = 0; j < n; ++j) //寻找最小的d[u] {
if (vis[j] == false && d[j] < MIN){
u = j;
MIN = d[j];
}
}
//找不到小于INF的d[u],说明剩下的顶点和起点s不连通
if (u == -1)return;
vis[u] = true; //标记u被访问
for (int j = 0; j < Adj[u].size(); ++j){
int v = Adj[u][j].v; //通过邻接表获取u能直接到达的v
if (vis[v] == false && d[v] > d[u] + Adj[u][j].dis)
d[v] = d[u] + Adj[u][j].dis; //优化d[u]
}
}
}
优先队列优化版:
/*
* 使用优先队列优化 Dijkstra 算法
* 复杂度 O(ElogE)
* 注意对 vector<Edge>E[MAXN] 进行初始化后加边
*/
const int INF=0x3f3f3f3f;
const int MAXN = 1000010;
struct qnode {
int v;
int c;
qnode(int _v = 0, int _c = 0) : v(_v), c(_c){}
bool operator<(const qnode &r) const{
return c > r.c;
}
};
struct Edge {
int v, cost;
Edge(int _v = 0, int _cost = 0) : v(_v), cost(_cost){}
};
vector<Edge> E[MAXN];
bool vis[MAXN];
int dist[MAXN];
// 点的编号从 1 开始
void Dijkstra(int n, int start)
{
memset(vis, false, sizeof(vis));
for (int i = 1; i <= n; i++)
dist[i] = INF;
priority_queue<qnode> que;
while (!que.empty())
que.pop();
dist[start] = 0;
que.push(qnode(start, 0));
qnode tmp;
while (!que.empty()) {
tmp = que.top();
que.pop();
int u = tmp.v;
if (vis[u])continue;
vis[u] = true;
for (int i = 0; i < E[u].size(); i++) {
int v = E[tmp.v][i].v;
int cost = E[u][i].cost;
if (!vis[v] && dist[v] > dist[u] + cost) {
dist[v] = dist[u] + cost;
que.push(qnode(v, dist[v]));
}
}
}
}
void addedge(int u, int v, int w){
E[u].push_back(Edge(v, w));
}