数据结构--画画--最小生成树(Prim算法)

通信网络的最小生成树配置,它是使右侧的生成树值并最小化。经常使用Prim和Kruskal算法。看Prim算法:以防万一N={V,{E}}它是在通信网络,TE它是N设置边的最小生成树。从算法U={u0}(uo属于V)。TE={}开始,复运行下述操作:在全部u属于U。v属于V-U的边(u,v)属于E中找到代价最小的一条边(u0,v0)并入集合TE,同一时候v0并入U,直至U=V为止。此时TE中必有n-1条边,T={V,{TE}}为N的最小生成树。

为实现此算法,需另设一个辅助数组closedge,以记录从U到V-U中具有最小权值的边。每次有新的顶点并入U,就要更新一次closedge。

详细代码例如以下:

#include <iostream>
#include <queue>
#include <limits.h>
#include "../Header.h"
using namespace std;
//普里姆算法构造最小生成树

const int MAX_VERTEX_NUM=20;  //最大顶点数
typedef enum {DG,DN,UDG,UDN} GraphKind ;//(有向图。有向网。无向图,无向网)
typedef int VRType;
typedef char InfoType;
typedef char VertexType;
#define INFINITY INT_MAX

typedef struct ArcCell{
    VRType adj;  //VRType是顶点关系类型,对于无权图。用1或者0表示顶点相邻与否。对于有权图。则为权值类型
    InfoType  info;//该弧相关信息指针
    ArcCell(){
        adj=0;
        info=0;
    }
}ArcCell,AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];

typedef struct MGraph{
    VertexType vexs[MAX_VERTEX_NUM]; //顶点向量
    AdjMatrix arcs;  //邻接矩阵
    int vexnum,arcnum;  //图当前的顶点数和弧数
    GraphKind kind;  //图的种类标志
}MGraph;

//记录从顶点集U到V-U的代价最小的边的辅助数组定义
typedef struct minedge{
    VertexType adjvex;
    VRType lowcost;
}minedge,Closedge[MAX_VERTEX_NUM];

int minimum(MGraph G,Closedge closedge){
    int min=1;
    for(int i=1;i<G.vexnum;++i){
        if(closedge[i].lowcost!=0){
                min=i;
                break;
            }
    }
    for(int i=min+1;i<G.vexnum;++i){
        if(closedge[i].lowcost<closedge[min].lowcost&&closedge[i].lowcost>0)
            min=i;
    }
    return min;
}

int LocateVex(MGraph G,VertexType v1){
    for(int i=0;i<MAX_VERTEX_NUM;++i){
        if(G.vexs[i]==v1)
        return i;
    }
    return MAX_VERTEX_NUM+1;
}

Status CreateUDN(MGraph &G){//採用数组(邻接矩阵)表示法。构建无向网
    G.kind=UDN;  //手动赋值为无向网
    int vexnumber=0,arcnumber=0;
    char info;
    cout<<"please input the vexnumber arcnumber and info:";
    cin>>vexnumber>>arcnumber>>info;
    G.vexnum=vexnumber;
    G.arcnum=arcnumber;
    for(int i=0;i<G.vexnum;++i){ //构造顶点向量
        cout<<"please input the vertex of number "<<i<<"(type char) ";
        cin>>G.vexs[i];
    }
    for(int i=0;i<G.vexnum;++i)  //初始化邻接矩阵
        for(int j=0;j<G.vexnum;++j){
            G.arcs[i][j].adj=INFINITY;
            G.arcs[i][j].info=0;
        }
    char v1,v2;
    int weight=0,i=0,j=0;
    char infomation;
    for(int k=0;k<G.arcnum;++k){  //初始化邻接矩阵
        cout<<"please input the two vertexs of the arc and it's weight "<<k+1<<" ";
        cin>>v1>>v2>>weight;
        i=LocateVex(G,v1);  j=LocateVex(G,v2);
        G.arcs[i][j].adj=weight;
        G.arcs[j][i].adj=weight;
        if(info!=48){//0的ascii码为48
            cout<<"please input infomation: ";
            cin>>infomation;
            G.arcs[i][j].info=infomation;
            G.arcs[j][i].info=infomation;
        }
    }
    return OK;
}

void DisMGraph(MGraph m){
    for(int i=0;i<m.vexnum;++i){
        for(int j=0;j<m.vexnum;++j){
            cout<<m.arcs[i][j].adj<<" ";
        }
        cout<<endl;
    }
}

//普里姆算法
void MiniSpanTree_Prim(MGraph G,VertexType u){
    int p=LocateVex(G,u);
    Closedge closedge;
    for(int j=0;j<G.vexnum;++j){  //辅助数组初始化
        if(j!=p)
            closedge[j].adjvex=u;
            closedge[j].lowcost=G.arcs[p][j].adj;
    }
    closedge[p].lowcost=0;
    closedge[p].adjvex=u;
    int k=0;
    for(int i=1;i<G.vexnum;++i){
        k=minimum(G,closedge);
        cout<<closedge[k].adjvex<<"--"<<G.vexs[k]<<endl;
        closedge[k].lowcost=0;
        for(int j=0;j<G.vexnum;++j){ //更新closedge数组
            if(G.arcs[k][j].adj<closedge[j].lowcost&&G.arcs[k][j].adj!=0){
                closedge[j].adjvex=G.vexs[k];
                closedge[j].lowcost=G.arcs[k][j].adj;
            }
        }
    }
}

int main()
{
    MGraph m;
    CreateUDN(m);
    DisMGraph(m);
    MiniSpanTree_Prim(m,'a');
    return 0;
}

版权声明:本文博客原创文章,博客,未经同意,不得转载。

时间: 2024-07-30 01:11:42

数据结构--画画--最小生成树(Prim算法)的相关文章

数据结构:最小生成树--Prim算法

最小生成树:Prim算法 最小生成树 给定一无向带权图,顶点数是n,要使图连通只需n-1条边,若这n-1条边的权值和最小,则称有这n个顶点和n-1条边构成了图的最小生成树(minimum-cost spanning tree). Prim算法 Prim算法是解决最小生成树的常用算法.它采取贪心策略,从指定的顶点开始寻找最小权值的邻接点.图G=<V,E>,初始时S={V0},把与V0相邻接,且边的权值最小的顶点加入到S.不断地把S中的顶点与V-S中顶点的最小权值边加入,直到所有顶点都已加入到S中

最小生成树--prim算法

一个无向图G的最小生成树就是由该图的那些连接G的所有顶点的边构成的树,且其总价值最低,因此,最小生成树存在的充分必要条件为图G是连通的,简单点说如下: 1.树的定义:有n个顶点和n-1条边,没有回路的称为树 生成树的定义:生成树就是包含全部顶点,n-1(n为顶点数)条边都在图里就是生成树 最小:指的是这些边加起来的权重之和最小 2.判定条件:向生成树中任加一条边都一定构成回路 充分必要条件:最小生成树存在那么图一定是连通的,反过来,图是连通的则最小生成树一定存在 上图的红色的边加上顶点就是原图的

hdu 3371 最小生成树prim算法

Connect the Cities Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 8992    Accepted Submission(s): 2519 Problem Description In 2100, since the sea level rise, most of the cities disappear. Thoug

POJ1258最小生成树(prim算法)

POJ1258 思路:首先把第一个结点加入树中,每次往树中加入一个结点,加入的结点必须是与当前树中的结点距离最小那个点,这样每次把结点加入树中选取的都是最小权值,循环n-1次后把所有结点都加入树中. #include<iostream> #include<cstdio> #include<cstring> using namespace std; const int MAXN = 1e9; //创建map二维数组储存图表,low数组记录每2个点间最小权值,vis数组标记

poj1789Truck History(最小生成树prim算法)

题目链接: 啊哈哈,点我点我 思路:根据字符串中不同的长度建图,然后求图的最小生成树.. 题目: Truck History Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 18272   Accepted: 7070 Description Advanced Cargo Movement, Ltd. uses trucks of different types. Some trucks are used for vege

最小生成树のprim算法

Problem A Time Limit : 1000/1000ms (Java/Other)   Memory Limit : 32768/32768K (Java/Other) Total Submission(s) : 31   Accepted Submission(s) : 10 Problem Description 省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可).经过调查评估,得到的统计表中列出了有可能建设公

无向图最小生成树Prim算法

问题 无向图最小生成树的Prim算法.一般的实现过程,采用了常规排序.本文在用Python实现中,使用了python的堆排序模块,不仅精简代码,而且提高效率. 思路说明 假设点A,B,C,D,E,F,两点之间有连线的,以及它们的距离分别是:(A-B:7);(A-D:5);(B-C:8);(B-D:9);(B-E:7);(C-E:5);(D-E:15);(D-F:6);(E-F:8);(E-G:9);(F-G:11) 关于Prim算法的计算过程,参与维基百科的词条:[普里姆算法] 将上述点与点关系

E - Agri-Net (最小生成树) -- prim算法

http://acm.sdut.edu.cn:8080/vjudge/contest/view.action?cid=193#problem/E prim算法 思想和步骤总结 (自己所写) dis[],map[][],vis[],pos ,min,ans(主要定义的变量) 首先,prim算法用于计算图边径长度已知的图,它所求的是将图中所有顶点相连接,所需要的最短路径的长度,prim算法适合计算稠密图,它的主要思想是贪心思想,贪心准则为每次选择未加入树中且距离树最小的顶点,并用dis[]数组不断更

Highways POJ-1751 最小生成树 Prim算法

Highways POJ-1751 最小生成树 Prim算法 题意 有一个N个城市M条路的无向图,给你N个城市的坐标,然后现在该无向图已经有M条边了,问你还需要添加总长为多少的边能使得该无向图连通.输出需要添加边的两端点编号即可. 解题思路 这个可以使用最短路里面的Prim算法来实现,对于已经连接的城市,处理方式是令这两个城市之间的距离等于0即可. prim算法可以实现我们具体的路径输出,Kruskal算法暂时还不大会. 代码实现 #include<cstdio> #include<cs