Я написал код, который решает MST с использованием метода Prim. Я прочитал, что такая реализация (с использованием очереди приоритетов) должна иметь O (E + VlogV) = O (VlogV), где E - количество ребер и V число краев, но когда я смотрю на свой код, он просто не выглядит Так и было бы. Я был бы признателен, если бы кто-то мог это очистить.Время работы минимального остовного дерева? (Метод Prim)
Мне кажется, время работы заключается в следующем:
в то время как цикл занимает O (E) раз (пока мы не пройти через все края) Внутри этого цикла мы извлечь элемент из Q, которая принимает O (logE). И второй внутренний цикл занимает O (V) время (хотя мы не запустить этот цикл каждый раз то ясно, что он будет побежал V раз, так как мы должны добавить все вершины)
Мой вывод был бы, что время работы: O (E (logE + V)) = O (E * V).
Это мой код:
#define p_int pair < int, int >
int N, M; //N - nmb of vertices, M - nmb of edges
int graph[100][100] = { 0 }; //adj. matrix
bool in_tree[100] = { false }; //if a node if in the mst
priority_queue< p_int, vector <p_int>, greater <p_int> > Q;
/*
keeps track of what is the smallest edge connecting a node in the mst tree and
a node outside the tree. First part of pair is the weight of the edge and the
second is the node. We dont remember the parent node beaceuse we dont need it :-)
*/
int mst_prim()
{
Q.push(make_pair(0, 0));
int nconnected = 0;
int mst_cost = 0;
while(nconnected < N)
{
p_int node = Q.top(); Q.pop();
if(in_tree[ node.second ] == false)
{
mst_cost += node.first;
in_tree[ node.second ] = true;
for(int i = 0; i < N; ++i)
if(graph[ node.second ][i] > 0 && in_tree[i]== false)
Q.push(make_pair(graph[ node.second ][i], i));
nconnected++;
}
}
return mst_cost;
}
Я знаю алгоритм Крускальса, но я тоже хотел понять это :-). Если я использую списки смежности для Prim, я получаю: while + for loop петли по всем краям и вставляет их в кучу. Это должно быть тогда E * log (E). Является ли это лучшей сложностью, которую вы можете получить с помощью этого подхода (используя кучу, а не кучу Fibbonaci)? – synepis
Да, вы проверяете каждое ребро не чаще двух раз (с обоих узлов), а очередь имеет крайние ребра по максимуму, что приводит к O (E log E). Но мы этого не пишем, потому что постоянные факторы не имеют отношения к O() нотации. Таким образом, O (E log E) = O (E log (V^2)) = O (E * 2 log V) = O (E log V). – supo
Это (комментарий выше) - это ответ, который я хотел, спасибо, я понимаю сейчас :-) – synepis