您的位置:首页 > 其它

Prim算法实现类

2012-03-23 10:22 330 查看
来复习复习最小生成树的算法,其中的prim算法比较简单。虽说用一般的邻接矩阵需要O(V2)的的时间复杂度。但是改为邻接表之后,会稍微提高到O(E
log(V))。

不过,这个,测试数据输错了,把我郁闷了半个钟头。太大意了。

这个Prim算法的原理呢,和Dijkstra算法有些类似。一个小城镇的扩张,慢慢侵蚀离它最近的点,吞噬成为其一部分,然后再继续吞噬。

Wiki上给出的比较好懂,我的比较抽象了。如下:

从单一顶点开始,普里姆算法按照以下步骤逐步扩大树中所含顶点的数目,直到遍及连通图的所有顶点。

输入:一个加权连通图,其中顶点集合为V,边集合为E;
初始化:Vnew = {x},其中x为集合V中的任一节点(起始点),Enew = {};
重复下列操作,直到Vnew = V:

在集合E中选取权值最小的边(u, v),其中u为集合Vnew中的元素,而v则不是(如果存在有多条满足前述条件即具有相同权值的边,则可任意选取其中之一);
将v加入集合Vnew中,将(u, v)加入集合Enew中;

输出:使用集合Vnew和Enew来描述所得到的最小生成树。

代码如下:

#include <iostream>
#include <queue>

#define MAX_VERTEX 15
#define MAX_EDGE 25
#define AL_END -1

using namespace std;

struct Edge
{
int next;
int vertex;
int cost;
};

struct Vertex
{
int cost;
int vertex;
};

bool operator <(const Vertex &a, const Vertex &b)
{
return a.cost > b.cost;
}

class AlGraph
{
public:
int smallestCost;
void prim();

private:
int vertexNum;
int edgeNum;
int AlVertex[MAX_VERTEX];
Edge edge[MAX_EDGE];
bool vertexDealed[MAX_VERTEX];
priority_queue<Vertex> primQueue;

void initialize();
void getData();
};

void AlGraph::initialize()
{
smallestCost = 0;

memset(AlVertex, AL_END,sizeof(AlVertex));
memset(vertexDealed, 0, sizeof(vertexDealed));

while (!primQueue.empty())
{
primQueue.pop();
}
}

void AlGraph::getData()
{
initialize();

cout << "Please input the vertex number: ";
cin >> vertexNum;

cout << "Please input the edge number: ";
cin >> edgeNum;

int source, destination, cost;
int ip = 0;
cout << "Please input the edges(source, destination, cost)." << endl;
for (int i = 0; i < edgeNum; i++)
{
cin >> source >> destination >> cost;
edge[ip].next = AlVertex[source];
edge[ip].cost = cost;
edge[ip].vertex = destination;
AlVertex[source] = ip++;

swap(source, destination);

edge[ip].next = AlVertex[source];
edge[ip].cost = cost;
edge[ip].vertex = destination;
AlVertex[source] = ip++;
}
}

void AlGraph::prim()
{
getData();

int gotNum = 0;

Vertex firstVertex;
firstVertex.cost = 0;
firstVertex.vertex = 0;
primQueue.push(firstVertex);

while (gotNum < vertexNum)
{
if (primQueue.empty())
{
cout << "Islet discovered!" << endl;
break;
}

Vertex nowvertex = primQueue.top();
primQueue.pop();

if (vertexDealed[nowvertex.vertex])
{
continue;
}

gotNum++;
smallestCost += nowvertex.cost;
vertexDealed[nowvertex.vertex] = true;

for (int i = AlVertex[nowvertex.vertex]; i != AL_END; i = edge[i].next)
{
if (!vertexDealed[edge[i].vertex])
{
nowvertex.cost = edge[i].cost;
nowvertex.vertex = edge[i].vertex;
primQueue.push(nowvertex);
}
}
}
}

int main()
{
AlGraph test;

test.prim();

cout << "The smallest cost is: " << test.smallestCost << endl;

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: