Prime算法构造最小生成树

最小生成树:包含图中全部顶点的极小联通子图。

极小:因为要取全部顶点,所以边要取最少,n个结点最少有n-1条边。边多了可能会导致回路,边少了会不连通。

Prime算法:加点法

假设顶点集V={v0,v1,v2,v3,v4},U是空集

(1)从顶点集V中任意选取一个顶点放入U,假设选取v0

则U={v0},V-U={v1 , v2 , v3 , v4 , v5 }

cost={(v0 , v1)34,(v0 , v2)46,(v0, v3)∞,(v0 , v4)∞,(v0, v5 )19}

 

 (2) 第一次迭代:

U={v0 , v5 },V-U={v1 , v2 , v3 , v4}

cost={(v0 , v1)34,(v5 , v2)25,(v5, v3)25,(v5 , v4)26} 

(3)第二次迭代:

U={v0 , v5 , v2 },V-U={v1 , v3 , v4 }

cost ={(v0 , v1)34, (v2, v3)17, (v5 , v4)26}

此时要找v1到U中顶点的最小权值,只需比较(v0,v1)25和(v2,v1)∞

此时要找v3到U中顶点的最小权值,只需比较(v5,v3)25和(v2,v3)17

此时要找v4到U中顶点的最小权值,只需比较(v5,v4)25和(v2,v4)∞

(4)第三次迭代:

U={v0 , v5, v2 , v3 },V-U={v1 ,  v4}

cost={(v0 , v1)34,(v5 , v4)26

 (5)第四次迭代:

U={v0 , v5, v2 , v3 , v4 },V-U={v1 }

cost ={(v4 , v1)12}

最终结果:

 

 

#include <iostream>

using namespace std;
class MGraph{
public:
    MGraph(char a[],int n,int e);
    void Prim(int v);
private:
    char vertex[100];//存放图中顶点
    int edge[100][100];//存放图中边
    int vertexNum,edgeNum;
    int MinEdge(int r[],int n);
};
MGraph::MGraph(char a[],int n,int e){
    int i,j,k,w;
    vertexNum=n;
    edgeNum=e;
    for(i=0;i<vertexNum;i++)//存储顶点
        vertex[i]=a[i];
    for(i=0;i<vertexNum;i++){//初始化邻接矩阵
        for(j=0;j<vertexNum;j++){
            if(i==j)
                edge[i][j]==0;
            else
                edge[i][j]=100;//假设边上的权值最大是100
        }
    }
    for(k=0;k<edgeNum;k++){
            cout<<"请输入边两个顶点的编号和边上的权值:"<<endl;
            cin>>i>>j>>w;
            edge[i][j]=w;
            edge[j][i]=w;
        }
}

void MGraph::Prim(int v){//从顶点v出发
    int i,j,k;
    int adjvex[100];//候选最短边的邻接点
    int lowcost[100];//候选最短边的权值
    lowcost[v]=0;//把顶点v加入集合U
    for(i=0;i<vertexNum;i++){
        lowcost[i]=edge[v][i];
        adjvex[i]=v;
    }
    for(k=1;k<vertexNum;k++){//迭代n-1次
        j=MinEdge(lowcost,vertexNum);//找出每次V-U到U的最小权值对应的j
        cout<<j<<" "<<adjvex[j]<<" "<<lowcost[j]<<endl;
        lowcost[j]=0;//把顶点j加入U
        for(i=0;i<vertexNum;i++){
                if(edge[i][j]<lowcost[i]){
                    lowcost[i]=edge[i][j];
                    adjvex[i]=j;
                  }
            }
      }
}

int MGraph::MinEdge(int r[],int n){
    int i,index=0;
    int min=100;//假设边上的权值最大是100
    for(i=1;i<n;i++){
        if(r[i]!=0&&r[i]<min){
            min=r[i];
            index=i;
        }
    }
    return index;
}
int main( )
{
	char ch[6]={'A','B','C','D','E','F'};
	MGraph mg(ch,6,9);
	mg.Prim(0);
	return 0;
}

运行结果
请输入边两个顶点的编号和边上的权值:
0 1 34
请输入边两个顶点的编号和边上的权值:
0 2 46
请输入边两个顶点的编号和边上的权值:
0 5 19
请输入边两个顶点的编号和边上的权值:
1 4 12
请输入边两个顶点的编号和边上的权值:
2 3 17
请输入边两个顶点的编号和边上的权值:
2 5 25
请输入边两个顶点的编号和边上的权值:
3 4 38
请输入边两个顶点的编号和边上的权值:
3 5 25
请输入边两个顶点的编号和边上的权值:
4 5 26

5 0 19
2 5 25
3 2 17
4 5 26
1 4 12

 

 

  • 14
    点赞
  • 66
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值