#include<stdio.h>
#include<iostream>
#include<algorithm>
using namespace std;
#define MaxInt 32767
#define MaxNum 100
typedef struct{
int adjvex;//最小边在u中的那个顶点
int lowcost;//最小边上的权值
}VNode,closedge[MaxNum];
typedef struct{
closedge aa;
int vexs[MaxNum];
int arcs[MaxNum][MaxNum];
int vexnum,arcnum;//点数和边数
}AMGraph;
int locate(AMGraph G,int c){//查找点在顶点表的位置
int i;
for(i=0;i<G.vexnum;i++){
if(G.vexs[i]==c)
return i;
else
continue;
}
}
bool cmp(VNode &a,VNode &b)//sort排序(
{
return a.lowcost<b.lowcost;
}
int Min(AMGraph G) {
int i,j,m,n;
sort(G.aa,G.aa+G.arcnum,cmp);
for(i=0;i<G.arcnum;i++){
if(G.aa[i].lowcost!=0){
m=G.aa[i].adjvex;
n=locate(G,m);
for(j=0;j<G.arcnum;j++){
if(G.arcs[j][n]==G.aa[i].lowcost)
return j;//返回的是地址
}
}
}
}
void MiniSpanTree_prim(AMGraph &G,int u){//初始顶点u;从0开始
int k,i,j;
int u0,v0;
k=locate(G,u);//k为顶点U地址的下标
for(j=0;j<G.vexnum;j++){
if(j!=k){
G.aa[j].adjvex=u;//顶点
G.aa[j].lowcost=G.arcs[k][j]; //此时都是地址的下标
}
}
G.aa[k].lowcost=0;//初始时U={u}
for(i=1;i<G.vexnum;i++){//选择其余n-1个顶点生成n-1条边
k=Min(G);//求出T的下一个结点 书上说第k个顶点即地址
u0=G.aa[k].adjvex;//[u0,k] 顶点值
v0=G.vexs[k];//最小边的另一个顶点 //返回的K是地址 //都是顶点值
cout<<u0<<v0;
cout<<"\n";
G.aa[k].lowcost=0;//第k个顶点并入U集
for(j=0;j<G.vexnum;j++){
if(G.arcs[k][j]<G.aa[j].lowcost){
G.aa[j]={G.vexs[k],G.arcs[k][j]};
}
}
}
}
//关于普里姆算法,我们寻找的是U中的点到其他点的权值最小,所以在原有基础之上,我们需要做的便是 若U中新增顶点到其他顶点的权值比U中其他顶点到相同顶点的权值小,进行替换
//相应的adjex也改变了
int CreateUDN(AMGraph &G){
int i,j;
cout<<"请输入无向网的点数和变数";
cin>>G.vexnum>>G.arcnum;//中间两个大于号
for(i=0;i<G.vexnum;i++){//依此输入点的信息
cout<<"请输入点的信息";
cin>>G.vexs[i];
}
for(i=0;i<MaxNum;i++){//初始化矩阵
for(j=0;j<MaxNum;j++){
G.arcs[i][j]=MaxInt;
}
}
for(i=0;i<G.arcnum;i++){//构造矩阵根据边的值
int v1,v2;
int m,n,w;
cout<<"请输入边依附的顶点和权值";
cin>>v1>>v2>>w;
m=locate(G,v1);n=locate(G,v2);
G.arcs[m][n]=G.arcs[n][m]=w;
}
return 1;
}
void show(AMGraph G){
int i,j;
for(i=0;i<G.vexnum;i++){//输出邻接矩阵
for(j=0;j<G.vexnum;j++){
cout<<G.arcs[i][j];
cout<<" ";
}
cout<<"\n";
}
cout<<"\n";
for(i=0;i<G.vexnum;i++){//输出顶点表
cout<<G.vexs[i];
cout<<" ";
}
}
int main(){
int u;
AMGraph G;
CreateUDN(G);
show(G);
cout<<"输入开始顶点:";
cin>>u;
MiniSpanTree_prim(G,u);
return 1;
}
08-22