
Уменьшение ключа
Fib_Heap_Decrease_Key(H,x,k)
1 if k > key[x]
2 then error «Новый ключ больше текущего»
3 key[x] ← k
4 y ← p[x]
5 if y ≠ NULL и key[x] < key[y]
6 then Cut(H,x,y)
7 Cascading_Cut(H,y)
8 if key[x] < key[min[H]]
9 then min[H] ← x
Cut(H,x,y)
1 Удаление x из списка дочерних узлов y, уменьшение degree[y]
2 Добавление x в список корней H
3 p[x] ← NULL
4 mark[x] ← FALSE
Cascading_Cut(H,y)
1 z ← p[y]
2 if z ≠ NULL
3 then if mark[y] = FALSE
4 then mark[y] ← TRUE
5 else Cut(H,y,z)
6 Cascading_Cut(H,z)
Амортизированная стоимость уменьшения ключа не превышает O(1).
[Править]Удаление узла
Fib_Heap_Delete(H,x)
1 Fib_Heap_Decrease_Key(H,x, − ∞)
2 Fib_Heap_Extract_Min(H)
Амортизированное время работы процедуры равно O(lg n).
Алгоритм Дейкстры
Поиск кратчайшего пути между двумя вершинами в графе.
Реализация на основе очереди с приоритетами.
Сложность порядка O(n\log(n)).
#include <iostream>
#include <set>
#include <vector>
using namespace std;
typedef vector<int> vi;
typedef pair<int,int> ii;
typedef vector<ii> vii;
typedef vector<vii> vvii;
const int MAX = 1001;
const int MAXINT = 1000000000;
int n;
vvii G(MAX);
vi D(MAX, MAXINT);
void Dijkstra(int s)
{
set<ii> Q;
D[s] = 0;
Q.insert(ii(0,s));
while(!Q.empty())
{
ii top = *Q.begin();
Q.erase(Q.begin());
int v = top.second;
int d = top.first;
for (vii::const_iterator it = G[v].begin(); it != G[v].end(); it++)
{
int v2 = it->first;
int cost = it->second;
if (D[v2] > D[v] + cost)
{
if (D[v2] != 1000000000)
{
Q.erase(Q.find(ii(D[v2], v2)));
}
D[v2] = D[v] + cost;
Q.insert(ii(D[v2], v2));
}
}
}
}
int main()
{
//freopen("input.txt", "r", stdin);
//freopen("output.txt", "w", stdout);
int m, s, t = 0;
scanf("%d %d %d %d", &n, &m, &s, &t);
for (int i = 0; i < m; i++)
{
int a, b, w = 0;
scanf("%d %d %d", &a, &b, &w);
G[a - 1].push_back(ii(b - 1, w));
G[b - 1].push_back(ii(a - 1, w));
}
Dijkstra(s - 1);
printf("%d\n", D[t - 1]);
return 0;
}