Agri-Net的Prim演算法+優先順序佇列實現
阿新 • • 發佈:2019-01-30
#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;
}