Алгоритм Прима: различия между версиями
Перейти к навигации
Перейти к поиску
Ctrlalt (обсуждение | вклад) Нет описания правки |
Ctrlalt (обсуждение | вклад) Нет описания правки |
||
(не показаны 3 промежуточные версии этого же участника) | |||
Строка 1: | Строка 1: | ||
{| width="100%" | |||
| width="50%" | | |||
'''O(V<sup>2</sup>)''' | |||
int prim(vector<vector<Edge>> &graph) { | |||
vector<bool> visited(graph.size()); | |||
vector<int> dist(graph.size(), 1e9); | |||
dist[0] = 0; | |||
int mstWeight = 0; | |||
for (int i = 0; i < graph.size(); i++) { | |||
int nearestV = -1; | |||
for (int v = 0; v < graph.size(); v++) | |||
if (!visited[v] && (nearestV == -1 || dist[v] < dist[nearestV])) | |||
nearestV = v; | |||
visited[nearestV] = true; | |||
mstWeight += dist[nearestV]; | |||
for (auto &[from, to, weight] : graph[nearestV]) | |||
if (dist[to] > {{Changed|weight}}) | |||
dist[to] = {{Changed|weight}}; | |||
} | |||
return mstWeight; | |||
} | |||
Полностью аналогично реализации Дейкстры за O(V<sup>2</sup>). | |||
Единственная разница — в качестве расстояния до вершины используется длина не всего пути, а последнего ребра. | |||
| width="50%" | | |||
'''O(ElogV)''' | |||
int prim(vector<vector<Edge>> &graph) { | |||
{{Changed|1=vector<bool> visited(graph.size());}} | |||
vector<int> dist(graph.size(), 1e9); | |||
set<pair<int, int>> unvisited; | |||
dist[0] = 0; | |||
unvisited.insert({ dist[0], 0 }); | |||
int mstWeight = 0; | |||
while (!unvisited.empty()) { | |||
int nearestV = unvisited.begin()->second; | |||
unvisited.erase(unvisited.begin()); | |||
{{Changed|1=visited[nearestV] = true;}} | |||
mstWeight += dist[nearestV]; | |||
for (auto &[from, to, weight] : graph[nearestV]) { | |||
if ({{Changed|!visited[to]}} && dist[to] > {{Changed|weight}}) { | |||
unvisited.erase({ dist[to], to }); | |||
dist[to] = {{Changed|weight}}; | |||
unvisited.insert({ dist[to], to }); | |||
} | |||
} | |||
} | |||
return mstWeight; | |||
} | |||
Почти аналогично реализации Дейкстры за O(ElogV). | |||
В качестве расстояния до вершины используется длина не всего пути, а последнего ребра. | |||
В отличие от Дейкстры, использование visited обязательно (контртест — 1 2 2, 2 3 1). | |||
|} | |||
== Ссылки == | == Ссылки == | ||
* [http://e-maxx.ru/algo/mst_prim e-maxx.ru — Алгоритм Прима] | * [http://e-maxx.ru/algo/mst_prim e-maxx.ru — Алгоритм Прима] | ||
* [http://neerc.ifmo.ru/wiki/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%9F%D1%80%D0%B8%D0%BC%D0%B0 neerc.ifmo.ru/wiki — Алгоритм Прима] | * [http://neerc.ifmo.ru/wiki/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%9F%D1%80%D0%B8%D0%BC%D0%B0 neerc.ifmo.ru/wiki — Алгоритм Прима] | ||
* [http://brestprog.neocities.org/lections/mst.html brestprog.neocities.org — Минимальное остовное дерево. Алгоритм Прима. Алгоритм Крускала)] | |||
* [http://informatics.mccme.ru/course/view.php?id=6 informatics.mccme.ru — Курс «Алгоритмы на графах» — часть 8] | * [http://informatics.mccme.ru/course/view.php?id=6 informatics.mccme.ru — Курс «Алгоритмы на графах» — часть 8] | ||
* [http://algs4.cs.princeton.edu/lectures/43MinimumSpanningTrees.pdf algs4.cs.princeton.edu/lectures — 4.3 Minimum Spanning Trees] | |||
* [http://visualgo.net/mst.html VisuAlgo — Minimum Spanning Tree] | |||
* [http://github.com/indy256/codelibrary/blob/master/java/src/Prim.java CodeLibrary — Prim's algorithm in O(V^2)] | * [http://github.com/indy256/codelibrary/blob/master/java/src/Prim.java CodeLibrary — Prim's algorithm in O(V^2)] | ||
* [http://github.com/indy256/codelibrary/blob/master/java/src/PrimHeap.java CodeLibrary — Prim's algorithm in O(ElogV)] | * [http://github.com/indy256/codelibrary/blob/master/java/src/PrimHeap.java CodeLibrary — Prim's algorithm in O(ElogV)] |
Текущая версия от 03:52, 26 декабря 2021
O(V2) int prim(vector<vector<Edge>> &graph) { vector<bool> visited(graph.size()); vector<int> dist(graph.size(), 1e9); dist[0] = 0; int mstWeight = 0; for (int i = 0; i < graph.size(); i++) { int nearestV = -1; for (int v = 0; v < graph.size(); v++) if (!visited[v] && (nearestV == -1 || dist[v] < dist[nearestV])) nearestV = v; visited[nearestV] = true; mstWeight += dist[nearestV]; for (auto &[from, to, weight] : graph[nearestV]) if (dist[to] > weight) dist[to] = weight; } return mstWeight; } Полностью аналогично реализации Дейкстры за O(V2). Единственная разница — в качестве расстояния до вершины используется длина не всего пути, а последнего ребра. |
O(ElogV) int prim(vector<vector<Edge>> &graph) { vector<bool> visited(graph.size()); vector<int> dist(graph.size(), 1e9); set<pair<int, int>> unvisited; dist[0] = 0; unvisited.insert({ dist[0], 0 }); int mstWeight = 0; while (!unvisited.empty()) { int nearestV = unvisited.begin()->second; unvisited.erase(unvisited.begin()); visited[nearestV] = true; mstWeight += dist[nearestV]; for (auto &[from, to, weight] : graph[nearestV]) { if (!visited[to] && dist[to] > weight) { unvisited.erase({ dist[to], to }); dist[to] = weight; unvisited.insert({ dist[to], to }); } } } return mstWeight; } Почти аналогично реализации Дейкстры за O(ElogV). В качестве расстояния до вершины используется длина не всего пути, а последнего ребра. В отличие от Дейкстры, использование visited обязательно (контртест — 1 2 2, 2 3 1). |
Ссылки
- e-maxx.ru — Алгоритм Прима
- neerc.ifmo.ru/wiki — Алгоритм Прима
- brestprog.neocities.org — Минимальное остовное дерево. Алгоритм Прима. Алгоритм Крускала)
- informatics.mccme.ru — Курс «Алгоритмы на графах» — часть 8
- algs4.cs.princeton.edu/lectures — 4.3 Minimum Spanning Trees
- VisuAlgo — Minimum Spanning Tree
- CodeLibrary — Prim's algorithm in O(V^2)
- CodeLibrary — Prim's algorithm in O(ElogV)
- Algos — Minimum spanning tree using Prim algorithm