您的位置:首页 > 其它

最小生成树prim和kruskal

2012-05-28 10:23 435 查看
最小生成树是指在带权图的所有生成树中,权值和最小(耗费最小)的生成树。

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>

using namespace std;

#define N          6
#define M 0x7FFFFFFF //

string _vexs
= {"v1", "v2", "v3", "v4", "v5", "v6"};
int _arcs

= {
M, 6, 1, 5, M, M,
6, M, 5, M, 3, M,
1, 5, M, 5, 6, 4,
5, M, 5, M, M, 2,
M, 3, 6, M, M, 6,
M, M, 4, 2, 6, M
};

struct MGraph
{
int  vexnum;       //顶点数
int  arcnum;       //弧数
int (&arcs)

; //邻接矩阵
string (&vexs)
; //顶点集

MGraph():vexs(_vexs),arcs(_arcs)
{
vexnum = N;
arcnum = 10;
}
};

struct stAdjcost
{
string adjvex; //顶点
int lowcost;   //权重
stAdjcost():adjvex(),lowcost(0){}
};

struct stEdge
{
int row;
int col;
int weight;
stEdge(int r,int c, int w):row(r),col(c),weight(w){}
bool operator<(const stEdge& e)
{
return weight < e.weight;
}
};

int LocateVex(MGraph& graph, const string& u)
{
for (int i=0; i<graph.vexnum; ++i)
{
if (graph.vexs[i]==u)
{
return i;
}
}

return -1;
}

int minimun(stAdjcost* closedge)
{
int index   = -1;
int lowcost =  M;
for (int i=0; i<N; ++i)
{
if (closedge[i].lowcost>=0 && closedge[i].lowcost<lowcost)
{
index   = i;
lowcost = closedge[i].lowcost;
}
}

return index;
}

//普里姆算法
void prim(MGraph& graph, const string& u) //默认从第0个顶点(v1)开始出发
{
stAdjcost closedge
; //辅助数组
int k = LocateVex(graph, u);

closedge[k].lowcost = -1;//将顶点并入U集
for (int j=0; j<graph.vexnum; ++j)
{
if (j!=k)
{
closedge[j].adjvex  = u;
closedge[j].lowcost = graph.arcs[k][j];//
}
}

for (int i=1; i<graph.vexnum; ++i)//选择graph.vexnum - 1个顶点
{
k = minimun(closedge); //求出下一个节点
cout << closedge[k].adjvex << " -- " << graph.vexs[k] << "\t lowcost = " << closedge[k].lowcost << endl; //输出生成的边

closedge[k].lowcost = -1;//将顶点并入U集
for (int j=0; j<graph.vexnum; ++j)
{
if (graph.arcs[k][j] < closedge[j].lowcost)
{
closedge[j].adjvex  = graph.vexs[k];
closedge[j].lowcost = graph.arcs[k][j];
}
}
}
}

void join(int vexset[6], int row, int col)
{
int origin = vexset[col];
for (int i=0; i<6; ++i)
{
if (vexset[i]==origin)
{
vexset[i]=vexset[row];
}
}
}

//克鲁斯卡尔算法
void kruskal(MGraph& graph)
{
int vexset
= {0,1,2,3,4,5};//N个连通分量
vector<stEdge> edge;    //边集

//初始化边edge
for (int i=0; i<N; ++i)
{
for (int j=i; j<N; ++j)
{
if (graph.arcs[i][j]>=0 && graph.arcs[i][j]<M)
{
edge.push_back(stEdge(i,j,graph.arcs[i][j]));
}
}
}

std::sort(edge.begin(), edge.end());//边按权重排序

vector<stEdge>::iterator iter = edge.begin();
for (; edge.end()!=iter; ++iter)
{
int s1 = vexset[iter->row];
int s2 = vexset[iter->col];
if (s1!=s2)
{
join(vexset, iter->row, iter->col);//合并连通分量
cout << graph.vexs[iter->row] << " -- " << graph.vexs[iter->col] << "\t lowcost = " << iter->weight << endl; //输出生成的边
}
}
}

int main()
{
MGraph graph;

cout << "*********************prim*********************" << endl;
prim(graph, "v1");

cout << "*********************kruskal*********************" << endl;
kruskal(graph);

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