基于邻接矩阵存储的图的最小生成树的Prime算法
2013-05-26 15:37
543 查看
#include <iostream>
using namespace std;
#define MAXNODE 500//最大顶点个数
#define Inf 65535//无穷大
typedef char vertype;
struct VerNode
{
vertype vertex;//// 顶点信息,可以是字母表示,也可以是数字表示
//.....;//// 和顶点相关的其它信息,如顶点的度
};
struct Arc
{
int adj;// 两顶点之间是否存在关系,用1或0表示相邻否;如果是带权图,则为权值类型
//....;// 和弧(或边)相关的信息,如弧头、弧尾
};
struct MGraph//图的邻接矩阵表示类型
{
VerNode vex[MAXNODE];//顶点向量
Arc arcs[MAXNODE][MAXNODE];//邻接矩阵
int vexnum,arcnum;//图的当前顶点数和弧数
};
int sum=0;//保存所走路径的花费
MGraph CreatMGraph(MGraph g)//创建邻接矩阵
{
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>g.vex[i].vertex;
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
g.arcs[i][j].adj=Inf;//初始化邻接矩阵,各顶点间无路
}
}
int i,j,quan,e=0;
cin>>i>>j;//输入一条边依附顶点的序号
cin>>quan;
while(i&&j)//两顶点之一为0表示结束
{
e++;
g.arcs[i][j].adj=quan;g.arcs[j][i].adj=quan;
cin>>i>>j;cin>>quan;
}
g.vexnum=n;
g.arcnum=e;
return g;
}
int GraphLocateVertex(MGraph g,vertype v)//返回顶点v在图中的位置
{
for(int i=1;i<=g.vexnum;i++)
{
if(g.vex[i].vertex==v)
return i;
}
return -1;
}
void MiniSpanTreer_Prime(MGraph g,vertype v)
{//用Prime算法从第u个顶点出发构造以邻接矩阵存储的网G的最
//小生成树T,并且输出T的各条边
struct Closedge
{
vertype adjvex;//最小代价边依附的始顶点
int lowcost;// 最小代价
}closedge[MAXNODE];
int k=GraphLocateVertex(g,v);//任意选取一个顶点u出发,返回顶点v在图中的位置
int minimum;//保存生成树的下一个结点
int min=10000000;
for(int i=1;i<=g.vexnum;i++)
{
if(i!=k)
{
closedge[i].adjvex=v;
closedge[i].lowcost=g.arcs[k][i].adj;
if(closedge[i].lowcost<min&&closedge[i].lowcost!=-1)
{
min=closedge[i].lowcost;
minimum=i;
}
}
}
closedge[k].lowcost=-1;
cout<<g.vex[k].vertex<<endl;//输出生成树的顶点
for(int i=2;i<=g.vexnum;i++)
{
k=minimum;//此时closedge[k].lowcost=MIN{closedge[vi].lowcost |closedge [vi].lowcost >0, vi属于V-U}
sum+=closedge[k].lowcost;
cout<<g.vex[k].vertex<<endl;//输出生成树的顶点
closedge[k].lowcost=-1;//第k结点并入U集并置权值为-1,表示该顶点已经遍历过
min=10000000;
for(int i=1;i<=g.vexnum;i++)
{
if(g.arcs[k][i].adj<closedge[i].lowcost)//新顶点并入U后
{
closedge[i].adjvex=g.vex[k].vertex;
closedge[i].lowcost=g.arcs[k][i].adj;
}
if(closedge[i].lowcost<min&&closedge[i].lowcost!=-1)//重新选择最小边
{
min=closedge[i].lowcost;
minimum=i;
}
}
// for(int i=1;i<=g.vexnum;i++)
// {
// cout<<closedge[i].adjvex;
// cout<<" "<<closedge[i].lowcost<<" ";
// }
// cout<<endl;
}
}
int main()
{
MGraph g= CreatMGraph(g);
vertype v;
cin>>v;
//cout<<g.vexnum<<" "<<g.arcnum<<endl;
MiniSpanTreer_Prime(g,v);
cout<<"所需花费为:"<<sum<<endl;
return 0;
}
using namespace std;
#define MAXNODE 500//最大顶点个数
#define Inf 65535//无穷大
typedef char vertype;
struct VerNode
{
vertype vertex;//// 顶点信息,可以是字母表示,也可以是数字表示
//.....;//// 和顶点相关的其它信息,如顶点的度
};
struct Arc
{
int adj;// 两顶点之间是否存在关系,用1或0表示相邻否;如果是带权图,则为权值类型
//....;// 和弧(或边)相关的信息,如弧头、弧尾
};
struct MGraph//图的邻接矩阵表示类型
{
VerNode vex[MAXNODE];//顶点向量
Arc arcs[MAXNODE][MAXNODE];//邻接矩阵
int vexnum,arcnum;//图的当前顶点数和弧数
};
int sum=0;//保存所走路径的花费
MGraph CreatMGraph(MGraph g)//创建邻接矩阵
{
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>g.vex[i].vertex;
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
g.arcs[i][j].adj=Inf;//初始化邻接矩阵,各顶点间无路
}
}
int i,j,quan,e=0;
cin>>i>>j;//输入一条边依附顶点的序号
cin>>quan;
while(i&&j)//两顶点之一为0表示结束
{
e++;
g.arcs[i][j].adj=quan;g.arcs[j][i].adj=quan;
cin>>i>>j;cin>>quan;
}
g.vexnum=n;
g.arcnum=e;
return g;
}
int GraphLocateVertex(MGraph g,vertype v)//返回顶点v在图中的位置
{
for(int i=1;i<=g.vexnum;i++)
{
if(g.vex[i].vertex==v)
return i;
}
return -1;
}
void MiniSpanTreer_Prime(MGraph g,vertype v)
{//用Prime算法从第u个顶点出发构造以邻接矩阵存储的网G的最
//小生成树T,并且输出T的各条边
struct Closedge
{
vertype adjvex;//最小代价边依附的始顶点
int lowcost;// 最小代价
}closedge[MAXNODE];
int k=GraphLocateVertex(g,v);//任意选取一个顶点u出发,返回顶点v在图中的位置
int minimum;//保存生成树的下一个结点
int min=10000000;
for(int i=1;i<=g.vexnum;i++)
{
if(i!=k)
{
closedge[i].adjvex=v;
closedge[i].lowcost=g.arcs[k][i].adj;
if(closedge[i].lowcost<min&&closedge[i].lowcost!=-1)
{
min=closedge[i].lowcost;
minimum=i;
}
}
}
closedge[k].lowcost=-1;
cout<<g.vex[k].vertex<<endl;//输出生成树的顶点
for(int i=2;i<=g.vexnum;i++)
{
k=minimum;//此时closedge[k].lowcost=MIN{closedge[vi].lowcost |closedge [vi].lowcost >0, vi属于V-U}
sum+=closedge[k].lowcost;
cout<<g.vex[k].vertex<<endl;//输出生成树的顶点
closedge[k].lowcost=-1;//第k结点并入U集并置权值为-1,表示该顶点已经遍历过
min=10000000;
for(int i=1;i<=g.vexnum;i++)
{
if(g.arcs[k][i].adj<closedge[i].lowcost)//新顶点并入U后
{
closedge[i].adjvex=g.vex[k].vertex;
closedge[i].lowcost=g.arcs[k][i].adj;
}
if(closedge[i].lowcost<min&&closedge[i].lowcost!=-1)//重新选择最小边
{
min=closedge[i].lowcost;
minimum=i;
}
}
// for(int i=1;i<=g.vexnum;i++)
// {
// cout<<closedge[i].adjvex;
// cout<<" "<<closedge[i].lowcost<<" ";
// }
// cout<<endl;
}
}
int main()
{
MGraph g= CreatMGraph(g);
vertype v;
cin>>v;
//cout<<g.vexnum<<" "<<g.arcnum<<endl;
MiniSpanTreer_Prime(g,v);
cout<<"所需花费为:"<<sum<<endl;
return 0;
}
相关文章推荐
- 基于邻接矩阵存储的无向网图的创建,最小生成树算法实现完整代码
- 图——克鲁斯算法——构建最小生成树(采用邻接矩阵的方式存储)
- 算法导论-第23章-最小生成树:Prime算法(基于vector)的C++实现
- 基于邻接矩阵存储的图的最小生成树的Prime算法
- Prime算法求最小生成树 (邻接矩阵)
- 基于最小生成树的实时立体匹配算法简介
- 最小生成树(prime算法、kruskal算法) 和 最短路径算法(floyd、dijkstra)
- 基于最小生成树的实时立体匹配算法简介
- 最小生成树(prime 算法和克鲁斯卡尔算法)
- 最小生成树(Prime算法、Kruskal算法)和最短路径算法(Floyd算法、DijKstra算法)
- poj 1287(最小生成树prime算法)
- 最小生成树(prime算法、kruskal算法) 和 最短路径算法(floyd、dijkstra)
- POJ 2485 Highways【最小生成树最大边,Prime算法】
- Prime算法求最小生成树 (邻接表)
- 最小生成树(prime算法)裸题
- 最小生成树(prime算法、kruskal算法) 和 最短路径算法(floyd、dijkstra)
- Prime算法求最小生成树 (最小堆优化)
- 最小生成树(prime算法、kruskal算法) 和 最短路径算法(floyd、dijkstra)
- 最小生成树(prime算法、kruskal算法) 和 最短路径算法(floyd、dijkstra)
- 最小生成树(prime算法、kruskal算法) 和 最短路径算法(floyd、dijkstra)