[数据结构]最小生成树

最小生成树:构造连通网的最小代价生成树

1、Prim算法

Prim算法从图的顶点的方向出发,首先确定一个顶点,找到该顶点到任意其他顶点的连通代价,然后根据新确定的节点更新到下一个节点的连通代价。

数据结构声明:

struct Graph
{
    int vertexes[MAX];
    int arc[MAX][MAX];
    int sum_vertexes,sum_edges;
};

构造图:

void createGraph(Graph &graph)
{
    memset(graph.arc,0,sizeof(graph.arc));
    int x,y,weight;
    cout<<"输入顶点的总数"<<endl;
    cin>>graph.sum_vertexes;
    cout<<"输入边的总数"<<endl;
    cin>>graph.sum_edges;
    for(int i=0; i<graph.sum_vertexes; i++)
    {
        cout<<"输入第"<<i+1<<"个顶点的标识"<<endl;
        cin>>graph.vertexes[i];
    }
    for(int i=0; i<graph.sum_edges; i++)
    {
        cout<<"输入第"<<i+1<<"条边的起点 终点 权重"<<endl;
        cin>>x>>y>>weight;
        graph.arc[x][y]=graph.arc[y][x]=weight;
    }
}

Prim算法:

void Prim(Graph graph)
{
    int adjvex[MAX];
    int lowcost[MAX];
    lowcost[0]=-1;
    adjvex[0]=0;
    //初始化
    for(int i=1; i<graph.sum_vertexes; i++)
    {
        lowcost[i]=graph.arc[0][i];
        adjvex[i]=0;
    }
    //lowcost :-1表示顶点已经访问,0表示两顶点不相连,其他表示权重
    for(int i=1; i<graph.sum_vertexes; i++)
    {
        //权重<65535
        int min=65535;
        int k;
        for(int j=1; j<graph.sum_vertexes; j++)
        {
            if(lowcost[j]!=-1&&lowcost[j]!=0&&lowcost[j]<min)
            {
                min=lowcost[j];
                k=j;
            }
        }
        lowcost[k]=-1;
        cout<<adjvex[k]<<"   "<<k<<endl;
        //更新lowcost和adjvex
        for(int j=1; j<graph.sum_vertexes; j++)
        {
            if(lowcost[j]!=-1&&graph.arc[k][j]!=0&&(graph.arc[k][j]<lowcost[j]||lowcost[j]==0))
            {
                    lowcost[j]=graph.arc[k][j];
                    adjvex[j]=k;
            }
        }
    }
}

2、Kruskal算法

Prim算法从定点出发,Kruskal则从边的方向考虑,将图的每一条边按照连通代价按照从小到大的方式排序,然后一次将边加入到结果中,为了避免形成环,加入一个判断机制。

数据结构声明:

struct  Edge
{
    int start;
    int stop;
    int weight;
};

struct Graph
{
    Edge edge[MAX];
    int sum_edges;
};

构造图:

void createGraph(Graph &graph)
{
    int x,y,w;
    cout<<"输入边的总数"<<endl;
    cin>>graph.sum_edges;
    for(int i=0;i<graph.sum_edges;i++)
    {
        cout<<"输入第"<<i+1<<"条边的起点 终点 权重"<<endl;
        cin>>x>>y>>w;
        graph.edge[i].start=x;
        graph.edge[i].stop=y;
        graph.edge[i].weight=w;
    }
}

Kruskal算法

void sortEdges(Graph &graph)
{
    Edge temp;
    for(int i=0;i<graph.sum_edges;i++)
    {
        for(int j=i+1;j<graph.sum_edges;j++)
        {
            if(graph.edge[i].weight>graph.edge[j].weight)
            {
                temp=graph.edge[i];
                graph.edge[i]=graph.edge[j];
                graph.edge[j]=temp;
            }
        }
    }
}

int Find(int *parent,int t)
{
    while(parent[t]!=0)
        t=parent[t];
    return t;
}

void Kruskal(Graph graph)
{
    int m,n;
    int parent[MAX];
    //初始化
    for(int i=0;i<graph.sum_edges;i++)
        parent[i]=0;
    for(int i=0;i<graph.sum_edges;i++)
    {
            m=Find(parent,graph.edge[i].start);
            n=Find(parent,graph.edge[i].stop);
            if(m!=n)
            {
                parent[m]=n;
                cout<<graph.edge[i].start<<"   "<<graph.edge[i].stop<<"   "<<graph.edge[i].weight<<endl;
            }
    }
}

还是写代码想让图中两个不连通的顶点之间的连通代价用0表示,结果在实现的判断中就要多添加一些条件判断,如果使用正无穷大的话,就方便多了~~~

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-08-11 05:43:40

[数据结构]最小生成树的相关文章

HDU 2489 Minimal Ratio Tree(数据结构-最小生成树)

Minimal Ratio Tree Problem Description For a tree, which nodes and edges are all weighted, the ratio of it is calculated according to the following equation. Given a complete graph of n nodes with all nodes and edges weighted, your task is to find a

数据结构-最小生成树-普里姆算法

转自https://blog.csdn.net/ZGUIZ/article/details/54633115 首先仍然是预定义: 1 #define OK 1 2 #define ERROR 0 3 #define Max_Int 32767 4 #define MVNum 100 5 6 typedef int Status; 7 typedef char VerTexType; 8 typedef int ArcType; 9 10 struct{ 11 VerTexType adjvex;

白话数据结构之最小生成树

一:基本概念 1:什么是生成树? 对于图G<V,E>,如果其子图G'<V',E'>满足V'=V,且G'是一棵树,那么G'就是图G的一颗生成树.生成树是一棵树,按照树的定义,每个顶点都能访问到任何一个其它顶点.(离散数学中的概念),其中V是顶点,E是边,通俗来讲生成树必须包含原图中的所有节点且是连通的 比如 2:最小生成树 一个无向连通图G=(V,E),最小生成树就是联结所有顶点的边的权值和最小时的子图T,此时T无回路且连接所有的顶点,所以它必须是棵树.就是将原图的n个顶点用 n-1

数据结构_课程设计——最小生成树:室内布线

***************************************转载请注明出处:http://blog.csdn.net/lttree******************************************** 这道课程设计,费不少时间,太麻烦了= =.(明明是能力不够) ~~~~最小生成树:室内布线~~~~ 题目要求: 装修新房子是一项颇为复杂的工程,现在需要写个程序帮助房主设计室内电线的布局. 首先,墙壁上插座的位置是固定的.插座间需要有电线相连,而且要布置的整齐美

数据结构:最小生成树--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中

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

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

数据结构-图-最小生成树

最小生成树表示得是连通图的极小连通子图,它包含所有的的顶点,但足以生成n-1条边的数. 下面是我学习的内容和理解. 1.使用普里姆算法构成最小生成树. 先讲一下普里姆算法的思路.普里姆算法思路是这样的: 前提:G={V,E} 这个是我们图的定义这个应该是明白啥意思的. 1.现在定义一个V1表示一个空的新集合 2.首先随机的将V中的一个节点放入到V1中,作为遍历图开始位置 3.其次选取V1中的一个节点和选取V中的一个节点,使边的权值是E中最小的(必须是存在E中的,不然不是两个节点不是连通的,也没用

数据结构与算法问题 sdut oj 2144 最小生成树

题目描述 有n个城市,其中有些城市之间可以修建公路,修建不同的公路费用是不同的.现在我们想知道,最少花多少钱修公路可以将所有的城市连在一起,使在任意一城市出发,可以到达其他任意的城市. 输入 输入包含多组数据,格式如下. 第一行包括两个整数n m,代表城市个数和可以修建的公路个数.(n<=100) 剩下m行每行3个正整数a b c,代表城市a 和城市b之间可以修建一条公路,代价为c. 输出 每组输出占一行,仅输出最小花费. 示例输入 3 2 1 2 1 1 3 1 示例输出 2 #include

数据结构之最小生成树

最小生成树: 一个连通图的生成树是一个极小连通子图,它含有图中全部顶点,但只有足以构成一棵树的n-1条边.这种构造连通网的最小代价生成树称为最小生成树,详见数据结构之图(术语.存储结构.遍历). 求连通网的最小生成树有两种经典方法:普里姆(Prime)算法和克鲁斯卡尔(Kruskal)算法. 1.Prime算法 (1)算法描述 假设N=(V,{E})是连通网,TE是N上最小生成树中边的集合.从V中任选一个顶点u0,算法从U={u0}(u0∈V),TE={}开始,重复执行以下步骤: 在所有u∈U.