最小生成树算法(1)-----------prim

#include <iostream>
#include <iomanip>
using namespace std;
#define MaxVertexNum 100				//最大顶点数
#define INFINTY 65535                 //最大值 

typedef char VertexType;
typedef int AdjType;	

typedef struct {
	VertexType vertex[MaxVertexNum];					//顶点向量
	AdjType arcs[MaxVertexNum][MaxVertexNum];			//邻接矩阵
	int vexnum,arcnum;									//图的当前顶点数和弧数
}MGraph; 

//求最小生成树的辅助数组
typedef struct closedge{
	VertexType adjvex;             //记录最小边在U中的那个顶点
    int lowcost;                   //存储最小边的权重
}Closedge[MaxVertexNum];
Closedge closedge;

int LocateVex(MGraph *G,VertexType v);
void CreateUDN(MGraph *G);
void Prim(MGraph *G,VertexType u);
void display(MGraph *G);

int main()
{
	MGraph G;
    CreateUDN(&G);
    Prim(&G,'1');
	return 0;
}
/*
1 2 6
1 3 1
1 4 5
2 3 5
2 5 3
3 4 5
3 5 6
3 6 4
4 6 2
5 6 6
*/

//以无向带权图为例
void CreateUDN(MGraph *G)
{
    VertexType v1,v2;
    int weight; 

    //确定顶点数和弧数
    cout<<"请输入顶点数和边数:";
    cin>>G->vexnum>>G->arcnum;

     //确定各个顶点的值
     cout<<"请输入各顶点的值:";
     for(int i=0;i<G->vexnum;i++)
        cin>>G->vertex[i];

    //初始化邻接矩阵
     for (int i = 0; i < G->vexnum; ++i)
     {
         for(int j=0;j< G->vexnum;j++)
            G->arcs[i][j] = INFINTY;
     } 

     //确定邻接矩阵
     cout<<"请输入"<<G->arcnum<<"对顶点和相应的权重:\n";
     for(int k=0; k<G->arcnum; k++)
     {
        cin>>v1>>v2>>weight;
        int i = LocateVex(G,v1);
        int j = LocateVex(G,v2);
        if(i>=0 && j>=0)
        {
            G->arcs[i][j] = weight;
            G->arcs[j][i] = weight;
        }

     }
    display(G);
}

//求顶点位置函数
int LocateVex(MGraph *G,VertexType v)
{
    int i;
    for(i=0;i<G->vexnum;i++)
    {
        if(G->vertex[i] == v)
            return i;
    }
    return -1;
}

int Min(MGraph *G)
{
    int k;
    int min = INFINTY;
    for(int i=0;i<G->vexnum;i++)
    {
        if(closedge[i].lowcost!=0 && closedge[i].lowcost<min)
        {
            min = closedge[i].lowcost;
            k = i;
        }
    }
    return k;
}

void Prim(MGraph *G,VertexType u)
{
    int m,s=0;
    VertexType v0,u0;
    int k = LocateVex(G,u);
    closedge[k].lowcost = 0;	//讲当前顶点加入生成树中 

    //初始化V-U中的顶点的辅助数组(即开始顶点到其他各顶点的距离)
    for(int i=0;i<G->vexnum;i++)
    {
        if(i!=k)
        {
            closedge[i].adjvex = u;
            closedge[i].lowcost = G->arcs[k][i];
            //cout<<"----------"<<closedge[i].lowcost<<endl;
        }
    }

    //找n-1条边
	cout<<"最小生成树的边为:"<<endl;;
    for(int e=1;e<G->vexnum;e++)
    {

    	m = Min(G);
        u0 = closedge[m].adjvex;
        v0 = G->vertex[m];
        cout<<"("<<u0<<","<<v0<<")"<<endl;

		s+=closedge[m].lowcost;
		closedge[m].lowcost = 0;
		//在 v0顶点加入U中之后,更新closedge[i](即更新生成树到每一个非树顶点的距离)
       	for (int i = 0; i < G->vexnum; i++)
       	{
           	if(G->arcs[m][i]<closedge[i].lowcost)
           	{
                closedge[i].lowcost = G->arcs[m][i];
                closedge[i].adjvex = v0;
           	}
       	}
    }
    cout<<"最小生成树的权重之和为:"<<s<<endl;
}

void display(MGraph *G)
{
	cout<<"该图对应的临接矩阵为:"<<endl;
    for(int i=0;i<G->vexnum;i++)
    {
        for(int j=0;j<G->vexnum;j++)
        {
            cout<<setw(8)<<G->arcs[i][j];
        }
        cout<<endl;
    }  

}

时间: 2024-10-25 00:17:39

最小生成树算法(1)-----------prim的相关文章

最小生成树算法 1.Prim算法

最小生成树(MST):一个有N个点的图,边一定是大于等于N-1条边的.在这些边中选择N-1条出来,连接所有N个点.这N-1条边的边权之和是所有方案中最小的. Prim算法的时间复杂度时O(n^2)的,因此适用于稠密图的最小生成树,如果是稀疏图的情况下采用Kruskal算法更好. Prim算法蕴含了贪心的思想,其原理是把图中所有的点分成两个集合,一个集合(V)是已经在生成树中的点,另一个集合(G)是不在生成树中的点,然后寻找起点在V中,终点在G中的边中权值最小的边加入生成树,然后把终点从G移到V中

数据结构基础温故-5.图(中):最小生成树算法

图的“多对多”特性使得图在结构设计和算法实现上较为困难,这时就需要根据具体应用将图转换为不同的树来简化问题的求解. 一.生成树与最小生成树 1.1 生成树 对于一个无向图,含有连通图全部顶点的一个极小连通子图成为生成树(Spanning Tree).其本质就是从连通图任一顶点出发进行遍历操作所经过的边,再加上所有顶点构成的子图. 采用深度优先遍历获得的生成树称为深度优先生成树(DFS生成树),采用广度优先遍历获得的生成树称为广度优先生成树(BFS生成树).如下图所示,无向图的DFS生成树和BFS

城市之间的最短总距离(最小生成树算法)

求解城市之间的最短总距离是一个非常实际的问题,其大意如下: 某地区由n个城市,如何选择一条路线使各个城市之间的总距离最短? 1.最短总距离算法 先来分析一下上述问题.某个地区的n个城市构成一个交通图,可以使用图结构来描述此问题,其对应关系如下: 每个城市代表图中的一个顶点. 两个顶点间的边即两个城市之间的路径,边的权值代表了城市间的距离. 这样,求解各个城市之间的最短总距离问题就归结为该图的最小生成树问题. 2.最小生成树算法(prim算法) //最小生成树算法 static void Prim

hdu 1162 Eddy&#39;s picture 最小生成树入门题 Prim+Kruskal两种算法AC

Eddy's picture Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 7428    Accepted Submission(s): 3770 Problem Description Eddy begins to like painting pictures recently ,he is sure of himself to

Prim算法和Kruskal算法(图论中的最小生成树算法)

最小生成树在一个图中可以有多个,但是如果一个图中边的权值互不相同的话,那么最小生成树只可能存在一个,用反证法很容易就证明出来了. 当然最小生成树也是一个图中包含所有节点的权值和最低的子图. 在一个图中权值最小的那个边一定在最小生成树中,如果一个图包含环,环中权值最大的边一定不在最小生成树中,还有就是连接图的任意两个划分的边中权值最短的那一条一定在最小生成树中. 下面介绍两个算法. Prim算法 Prim算法就是以任意一个点为源点,将所有点分为两组,一组是已经在最小生成树上的点,另一组是还未在最小

无向带权图的最小生成树算法——Prim及Kruskal算法思路

边赋以权值的图称为网或带权图,带权图的生成树也是带权的,生成树T各边的权值总和称为该树的权. 最小生成树(MST):权值最小的生成树. 生成树和最小生成树的应用:要连通n个城市需要n-1条边线路.可以把边上的权值解释为线路的造价.则最小生成树表示使其造价最小的生成树. 构造网的最小生成树必须解决下面两个问题: 1.尽可能选取权值小的边,但不能构成回路: 2.选取n-1条恰当的边以连通n个顶点: MST性质:假设G=(V,E)是一个连通网,U是顶点V的一个非空子集.若(u,v)是一条具有最小权值的

Prim 最小生成树算法

Prim 算法是一种解决最小生成树问题(Minimum Spanning Tree)的算法.和 Kruskal 算法类似,Prim 算法的设计也是基于贪心算法(Greedy algorithm). Prim 算法的思想很简单,一棵生成树必须连接所有的顶点,而要保持最小权重则每次选择邻接的边时要选择较小权重的边.Prim 算法看起来非常类似于单源最短路径 Dijkstra 算法,从源点出发,寻找当前的最短路径,每次比较当前可达邻接顶点中最小的一个边加入到生成树中. 例如,下面这张连通的无向图 G,

hdu 1162 Eddy&amp;#39;s picture (Kruskal算法,prim算法,最小生成树)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1162 [题目大意] 给你n个点的坐标,让你找到联通n个点的一种方法.保证联通的线路最短,典型的最小生成树问题. 方法一 . 通过不断找到最小的边来找到终于结果. Kruskal 算法 #include <iostream> #include <algorithm> #include <cstdio> #include <cmath> using namespac

hdu 1162 Eddy&#39;s picture (Kruskal算法,prim算法,最小生成树)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1162 [题目大意] 给你n个点的坐标,让你找到联通n个点的一种方法,保证联通的线路最短,典型的最小生成树问题. 方法一 , 通过不断找到最小的边来找到最终结果. Kruskal 算法 #include <iostream> #include <algorithm> #include <cstdio> #include <cmath> using namespac