hiho 29 最小生成树三·堆优化的Prim算法
2016-01-23 16:54
330 查看
问题描述
最小生成树算法,在稀疏图时,Kruscal复杂度更低,我们可以使用堆优化的prim算法达到与Kruscal一样的复杂度。Prim算法本身的时间复杂度是O(N^2)的,而在这个算法中,使用了堆来维护所有的边,操作数一共是O(M)级别的,所以复杂度是O(MlogM)的!而Kruscal算法的时间复杂度是O(MlogM + M * Ackermann’(M)),总的说来,是优化到了和Kruscal算法同样级别了呢。”
prim 算法对应于dijstra算法。dijistra算法也可以用堆进行优化。
STL中heap函数
参考这个例子中,注意push_heap 和 pop_heap只是改变vector中元素位置,并不会插入或删除元素,所以要配合vector.push_back() 和 vector.pop_back()使用!// range heap example #include <iostream> // std::cout #include <algorithm> // std::make_heap, std::pop_heap, std::push_heap, std::sort_heap #include <vector> // std::vector int main () { int myints[] = {10,20,30,5,15}; std::vector<int> v(myints,myints+5); std::make_heap (v.begin(),v.end()); std::cout << "initial max heap : " << v.front() << '\n'; std::pop_heap (v.begin(),v.end()); v.pop_back(); std::cout << "max heap after pop : " << v.front() << '\n'; v.push_back(99); std::push_heap (v.begin(),v.end()); std::cout << "max heap after push: " << v.front() << '\n'; std::sort_heap (v.begin(),v.end()); std::cout << "final sorted range :"; for (unsigned i=0; i<v.size(); i++) std::cout << ' ' << v[i]; std::cout << '\n'; return 0; }
#include <vector> #include <algorithm> #include <cstring> #include <cstdio> using namespace std; enum {maxn = 100000+5}; struct Node{ int a, b; int w; // 构建小顶堆 bool operator <(const struct Node &n)const{ return w> n.w; } }; vector<Node> edge; vector<Node> G[maxn]; bool visted[maxn]; void inline m_pop() {pop_heap(edge.begin(), edge.end()); edge.pop_back();} void inline m_push(struct Node &n) { edge.push_back(n); push_heap(edge.begin(), edge.end()); } int main() { //freopen("in.txt", "r", stdin); int N, M; scanf("%d %d", &N, &M); memset(visted, 0, sizeof(visted)); for (int i=0; i< M; i++) { int a, b, c; scanf("%d %d %d", &a, &b, &c); G[a].push_back(Node{a, b, c}); G[b].push_back(Node{b, a, c}); } visted[1] = true; for(int i=0; i< G[1].size(); i++) { m_push(G[1][i]); } int all =0; int cnt = 0; while(cnt < N-1){ int w = edge[0].w; int n = edge[0].b; m_pop(); if (visted ){ continue; } visted = true; all += w; cnt ++; for (int i=0; i< G .size(); i++) { if (!visted[G [i].b]) m_push(G [i]); } } printf("%d\n", all); return 0; }
相关文章推荐
- 最小生成树算法之Prim算法
- 最小生成树算法——Prim和Kruskal算法的实现
- 最小生成树
- 最小生成树之prim算法
- 图的最小生成树学习笔记
- POJ2485
- POJ 1258
- poj1789 2485 1258
- prim
- 最小生成树之prim算法
- POJ1287-Networking
- Sicily 1090. Highways
- hdu 1789 继续畅通工程
- hdu 4463 Outlets(prim)
- 最小生成树
- c#实现Prim算法
- prim 算法 最小生成树
- prim算法简介及实现
- 最小生成树之prim算法
- Introduce to algorithm--------pseudo code to C/C++ code (chapter 23)