dijkstra
单源最短路
O(mn)
O(mlogn)优先队列优化
理解:点与源最近的距离等于直接边权或中转后和距离 贪心思路-选择已探明的点中距离最小的点 只有从距离最小的点中转的点距离才会最小
/*
数据存储形式 带权邻接表 vector<pair<int, int>>e[N];
辅助数组
vis[N] 节点是否固定
优先队列
priority_queue<pair<int,int>>q;
*/
int d[N];
int n,m;
void dijkstra(int s) {
memset(d, 0x3f3f3f, sizeof(d));
d[s] = 0;
q.push({ 0,s });
st[s] = 1;
while(!q.empty()) {
int u = q.top().second;
q.pop();
if (vis[u] == 1)continue;//优先队列中有可能有同一个节点多次重复进入 距离最小的先出队 之后的出队时跳过
vis[u] = 1;
int num = e[u].size();
for (int j = 0; j < num; j++) {
int v = e[u][j].first;
int w = e[u][j].second;
if (d[v] > d[u] + w && vis[v] == 0) {
d[v] = d[u] + w;
q.push({-d[v], v});//即使点在队列中 距离更新后也要重复入队
}
}
}
}
floyd
多源最短路
O(n^3)
/*
数据存储形式 邻接矩阵d[i][j]
*/
void floyd() {
for (int i = 1; i <= n; i++) {//自身节点置零
d[i][i] = 0;
}
for (int k = 1; k <= n; k++) {
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
if (d[i][j] > d[i][k] + d[k][j]) d[i][j] = d[i][k] + d[k][j];
}
}
}
}
bellman_ford
单源最短路
O(nm)
理解:相当于从一点开始扩张 扩张n次 每次松弛所有扩张到的点
void bellman_ford(int s) {
memset(d, 0x3f3f, sizeof(d));
for (int i = 0; i < n-1; i++) {//最多n-1次遍历
int flag = 0;
for (int u = 1; u <= n; u++) {//遍历所有边 并松弛
if (d[u] == 0X3f3f)continue;
for (auto E : e[u]) {
int v = E.first;
int w = E.second;
if (d[v] > d[u] + w) {
d[v] = d[u] + w;
flag = 1;
}
}
}
if (flag == 0)break;//如果没有边需要松弛 则已经是最短路
}
}
浙公网安备 33010602011771号