题目链接:http://dsalgo.openjudge.cn/graph/2/
最小生成树算法,这是我第一次用优先队列实现Prim算法,记录一下
裸奔版
#include <iostream>
#include <queue>
using namespace std;
const int MAXN = 30;
const int INF = 1 << 20;
int lowest[MAXN]; //各节点到已有生成树的最短距离,
//树中节点为-1
int roads[MAXN][MAXN];
void initialize(int n)
{
for(int i = 0; i < n; ++i)
lowest[i] = INF;
for(int i = 0; i < n; ++i)
{
for(int j = 0; j < n; ++j)
{
roads[i][j] = INF;
}
roads[i][i] = 0;
}
}
int prim(int n)
{
int ret = 0;
int i, j, k;
lowest[0] = -1;
for(i = 1; i < n; ++i)
{
lowest[i] = roads[0][i];
}
for(i = 1; i < n; ++i) //每一轮迭代加入一个节点
{
int min = INF;
for(k = 0; k < n; ++k)
{
if(lowest[k] != -1 && lowest[k] < min)
{
min = lowest[k];
j = k;
}
}
ret += min;
lowest[j] = -1;
for(k = 0; k < n; ++k)
{
if(roads[j][k] < lowest[k]) lowest[k] = roads[j][k];
}
}
return ret;
}
int main()
{
std::ios::sync_with_stdio(false);
std::cin.tie(0);
int n, numOfFrom, weight;
char village, from;
while(cin >> n && n != 0) {
initialize(n);
for(int i = 0; i < n-1; ++i)
{
cin >> village >> numOfFrom;
for(int j = 0; j < numOfFrom; ++j)
{
cin >> from >> weight;
roads[village-'A'][from-'A'] = weight;
roads[from-'A'][village-'A'] = weight;
}
}
cout << prim(n) << endl;
}
return 0;
}
优先队列版
#include <iostream>
#include <queue>
#include <vector>
#include <cstring>
using namespace std;
const int MAXN = 30;
const int INF = 1 << 20;
struct Edge
{
int sta, end, weight;
Edge(int s = 0, int e = 0, int w = INF):
sta(s), end(e), weight(w){}
};
bool operator < (const Edge & l, const Edge & r){ return l.weight > r.weight; }
vector<Edge> nodesEdge[MAXN];
void initialize(int n)
{
for(int i = 0; i < n; ++i)
{
nodesEdge[i].clear();
}
}
int prim(int n)
{
int total, ret = 0, sta;
bool visit[n];
memset(visit, 0, sizeof(visit));
priority_queue<Edge> que;
total = 1;
visit[0] = true;
sta = 0;
while(total < n) {
for(auto e : nodesEdge[sta])
{
if(!visit[e.end])
{
que.push(e);
}
}
//注意会有多个副本存在队列里面,未曾访问过的才是能用的
while(!que.empty() && visit[que.top().end]) {
que.pop();
}
sta = que.top().end;
ret += que.top().weight;
visit[que.top().end] = true;
que.pop();
++total;
}
return ret;
}
int main()
{
std::ios::sync_with_stdio(false);
std::cin.tie(0);
int n, numOfFrom, weight;
char village, from;
while(cin >> n && n != 0) {
initialize(n);
for(int i = 0; i < n-1; ++i)
{
cin >> village >> numOfFrom;
for(int j = 0; j < numOfFrom; ++j)
{
cin >> from >> weight;
nodesEdge[village-'A'].push_back(Edge(village-'A', from-'A', weight));
nodesEdge[from-'A'].push_back(Edge(from-'A', village-'A', weight));
}
}
cout << prim(n) << endl;
}
return 0;
}