dijkstra 算法
- 单源最短路径算法
- 适用于有向图,无向图,图中不能出现负边
- 算法思想:
- 把源点到各点的距离初始化为无穷大
- 定义到源点的最短距离为0,把源点塞入一个优先队列中
- 每次都能从优先队列中取出一个最短距离,从优先队列中取出队头,如果队头的最短距离小于距离矩阵距离,那么更新距离矩阵,把该队头节点的扇出点放到优先队列中。已经算出最短距离的点,不再扩充,避免死循环。
- 算法特点:带优先队列的广度优先搜索,图中不能负权边,每个点的最短距离,仅仅会被更新一次。
- 算法复杂度:VlogV
- 代码:
double INF_D = INT_MAX / 2.0;
double EPS_D = 1e-6;
struct Dijkstra {
vector<double> dist;
vector<int> pre;
vector<int> path;
double run(Graph *g, int source, int sink) {
dist.clear(), pre.clear();
dist.resize(g->V, INF_D); pre.resize(g->V, -1);
priority_queue<Node> q;
Node n(source, 0.0, -1);
q.push(n);
while (!q.empty() && abs(dist[sink] - INF_D) < EPS_D) {
Node head = q.top(); q.pop();
if (head.dist < dist[head.id]) {
dist[head.id] = head.dist;
pre[head.id] = head.pre;
for (auto &e : g->edges[head.id]) {
if (abs(dist[e.to] - INF_D) < EPS_D) {
q.emplace(e.to, head.dist + e.cost, head.id);
}
}
}
}
return dist[sink];
}
void getPath(int source, int sink) {
path.clear();
int i = sink;
while (i != -1) {
path.push_back(i);
i = pre[i];
}
reverse(path.begin(), path.end());
}
};
Bellman-Ford算法