1. 程式人生 > >Agri-Net的Prim演算法+優先順序佇列實現

Agri-Net的Prim演算法+優先順序佇列實現

  • 優先權實現的prim 演算法複雜度的分析
  •     如果直接從程式碼來進行分析,我認為比較困難,所以直接從巨集觀上進行分析。 使用優先權佇列,假設極端情下每條邊都會進入佇列以替代原來權值較大的邊,進行建堆和調整,對m條邊排序總共花費mlogm。為了建立MST,至少要有n-1條邊從優先佇列中pop,這需要花費nlogm,於是整體時間複雜度為O(mlogm+nlogm),     顯然,存在MST的樹,邊數至少n-1條,最多(n×n-1)/2條,因為logm與logn同階,因此最終的複雜度為O(mlogn)。
  • Agri-Net:Prim演算法+優先順序佇列實現
  • #include<cstdio>
    #include<vector> #include<queue> using namespace std; struct Edge { int from, to; int weight; Edge(int f, int t, int w) :from(f), to(t), weight(w) {} bool operator <(const Edge& e)const { return this->weight > e.weight; } }; // prim 求MST int prim(vector<vector<int>>
    & vec) { priority_queue<Edge> myQueue; for (int i = 1; i < vec.size(); ++i) myQueue.emplace(0,i,vec[0][i]); vector<int> visit(vec.size(), 0); visit[0] = 1;// 標記第一個節點 int visitCount = 1;// 已經被加入到生成樹中節點個數 int MSTWeight = 0;// 最小生成樹的權值 while (visitCount < vec.size() && !myQueue.
    empty()){ Edge edge = myQueue.top(); myQueue.pop(); if (visit[edge.to] == 1)// 若該邊指向的另外一個點已被訪問,則跳過。 continue; visit[edge.to] = 1; // 標記訪問記號 ++visitCount; MSTWeight += edge.weight; for (int i = 0; i < vec.size(); ++i){ if (visit[i] == 0) myQueue.emplace(edge.to,i,vec[edge.to][i]);// 把與edge.to相連的邊全部加入到最小堆中 } } return MSTWeight; } int main() { int edgeLen; while (scanf("%d",&edgeLen)!=EOF){ vector<vector<int> > graph; int rowCount = edgeLen; while (0 < rowCount){ vector<int> tmpVec; int tmpColCount = edgeLen; while (0 < tmpColCount--){ int tmp; scanf("%d", &tmp); tmpVec.emplace_back(tmp); } graph.emplace_back(tmpVec); --rowCount; } printf("%d\n", prim(graph)); } return 0; }