普里姆算法之最小生成树

正在Coursera上学习C++ For C Programmers,学到了最小生成树这里,就以自己的思路尝试实现,小白写得比较粗糙。

普里姆算法有点贪婪算法的感觉,先找到一个开始点,然后将它所能到达的的点放入一个priority_queue记为Q,从中选取距离最短的点与开始点连接,一直持续下去直到Q为空,就构成了最小生成树,这里要注意不可选择重复点。

#include <iostream>
#include <queue>
#include <vector>
#include <climits>
#include <ctime>
#include <cstdlib>
#include <algorithm>

using namespace std;

class Graph{
private:
typedef pair<double, int> ii;
typedef pair<double, pair<int,int>> kk;
typedef pair<int, int> jj;
vector< vector<ii>> edge;
priority_queue<kk, vector<kk>, greater<kk>> Q;
vector<vector<int>> spanning_tree;
vector<int> done;
int V;
//double MAX_DISTANCE;

public:
Graph(int vertices=-1){
V = vertices;
//MAX_DISTANCE = static_cast<double>(INT_MAX);
edge.resize(V+1);
spanning_tree.resize(V+1);
}

bool already_been(int u){
vector<int> :: iterator ret;
ret = std::find(done.begin(), done.end(), u);
if(ret == done.end()) return false;
else return true;
}

void addEdge(int u, int v, double w){
edge[u].push_back(ii(w, v));
edge[v].push_back(ii(w, u));
}

void addtree(int u, int v){
spanning_tree[u].push_back(v);
spanning_tree[v].push_back(u);
}

void monteCarloSimulation(double density, double weightLO, double weightHI){
double probability, weight;
for(int i=0; i<50; ++i){
for(int j=i+1; j<50; ++j){
probability = static_cast<double>(rand())/RAND_MAX;
if(probability <= density){
weight = weightLO + (weightHI - weightLO) * (static_cast<double>(rand())/RAND_MAX);
addEdge(i, j, weight);
}
}
}
}

void findtree(int source){
int top,comefrom,leaf;
done.push_back(source);
for(int i=0; i<edge[source].size(); ++i) Q.push(kk(edge[source][i].first, jj(edge[source][i].second, source)));
while(!Q.empty()){
top = Q.top().second.first;
comefrom = Q.top().second.second;
Q.pop();
if(!already_been(top)){
done.push_back(top);
addtree(comefrom, top);
for(int j=0; j<edge[top].size(); ++j){
leaf = edge[top][j].second;
if(!already_been(leaf)) Q.push(kk(edge[top][j].first, jj(edge[top][j].second, top)));
}
}
}}

void printGraph(){
cout << "come to see the graph" << endl;
for(int i=0; i<V; ++i){
for(int j=0; j<edge[i].size(); ++j) cout << "(" << edge[i][j].second << "," << edge[i][j].first << ") ";
cout << endl;
}

}

void printtree(){
cout << "come to see the spanning tree" << endl;
for(int i=0; i<V ; ++i){
cout << "node " <<i << ": " ;
for(int j=0; j<spanning_tree[i].size(); ++j) cout << spanning_tree[i][j] << " ";
cout << endl;
}
}
};

int main(){
Graph G;
G = Graph(50);
G.monteCarloSimulation(0.05, 1.0, 10.0);
G.findtree(0);
//G.printGraph();
G.printtree();
}

posted @ 2019-01-03 21:18  王老吉味巧克力  阅读(586)  评论(0编辑  收藏  举报