我写了一个使用Prim方法解决MST的代码。我读到这种实现(使用优先级队列)应该有O(E + VlogV)= O(VlogV)其中E是边的数量和V的边数,但是当我查看我的代码时,它根本看不到如果有人能为我解决这个问题,我将不胜感激。最小生成树的运行时间? (Prim方法)
对我来说,似乎运行时间是这样的:
while循环需要O(E)次(直到我们经过所有的边) 在该循环中,我们从需要O将q提取元素(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;
}
我知道Kruskals算法,但我也想了解这一个:-)。如果我使用Prim的邻接列表,那么我得到:while + for循环遍历所有边并将它们插入到堆中。这应该是E * log(E)。这是用这种方法得到的最好的复杂性(使用堆而不是Fibbonaci堆)? – synepis 2010-01-10 12:40:13
是的,你检查每条边最多两次(来自两个节点),队列最多有E条边,这导致O(E log E)。但是我们不这样写,因为常数因子在O()表示法中是不相关的。所以O(E log E)= O(E log(V 2))= O(E * 2 log V)= O(E log V)。 – supo 2010-01-10 13:14:51
这个(上面的评论)是我想要的答案,谢谢我现在理解:-) – synepis 2010-01-11 20:52:22