最小生成树的算法

今天写了一个最小生成树的算法,也是为了准备蓝桥杯。题解再说,先专门讨论算法。

最小生成树的算法原理我一直都知道,就是代码一直不会写。简单说一下原理好了。一个无向无环图,每条边上有相应的权值,找到权值的和最小的生成树就是最小生成树。首先将所有的点分为两个集合U,V。其中U是已经找到对应边的点。每次寻找U到V的最短边,并且把这条边在V中的端点加入U。循环下去直到所有的点都被找到。

灵感来源于http://blog.chinaunix.net/uid-25324849-id-2182922.html

下面是代码,注释很清楚了(不连通的点距离是无穷大,自己到自己也是无穷大)

 1 #include<iostream>
 2 #include<stack>
 3 #include<stdio.h>
 4 #include<string.h>
 5 using namespace std;
 6 const int in = 1000;
 7 int main()
 8 {
 9     int map[5][5] = {{in,30,in,in,in},{30,in,40,40,70},{in,40,in,60,62},{in,40,60,in,60},{in,70,62,60,in}};
10     int cost[5];//当前点集合内的点到其他点的最短距离
11     int point[5];//在集合内的边(i,point[i])
12     bool visit[5];//该点在不在集合内
13     int father[5];//好像没什么用
14     int i;
15     //先将第一个点加入集合内并且给数组们赋值
16     for(i = 0;i < 5;i++)
17     {
18         cost[i] = map[0][i];
19         point[i] = 0;
20         visit[i] = false;
21         father[i] = 0;
22     }
23     visit[0] = true;
24     int k;
25     //有n个顶点就有n-1条边,进行n-1次循环求出这些边
26     for(k = 1;k < 5;k++)
27     {
28         int j = 0;
29         int min = in;
30         //找出不在集合内的与集合内的点距离最短的点
31         for(i = 0;i < 5;i++)
32         {
33
34             if(!visit[i] && min > cost[i]){min = cost[i];j = i;}
35         }
36         //将这个点加入集合
37         visit[j] = true;
38         father[j] = point[j];
39         //更新数组们
40         for(i = 0;i < 5;i++)
41         {
42             //对于还不在集合内点,如果与新加入的点的距离小于原来的距离就改变cost数组,
43             //并且将该点的边的另一端改为新加入的点
44             //i是不在集合里的点,j是刚才加入的点
45             if(!visit[i] && cost[i]>map[j][i]){cost[i] = map[j][i];point[i] = j;}
46         }
47         cout<<j<<" "<<point[j]<<endl;//打印出这个新加入的边
48     }
49     int sum = 0;
50     for(i = 1;i < 5;i++)
51     {
52         sum += map[i][point[i]];
53     }
54     cout<<sum;//最小生成树的权值之和
55     return 0;
56 }

时间: 2024-10-10 13:41:25

最小生成树的算法的相关文章

SOJ4339 Driving Range 最小生成树 kruskal算法

典型的最小生成树 然后求最大的一条边 附上链接 http://cstest.scu.edu.cn/soj/problem.action?id=4339 需要注意的是有可能有 "IMPOSSIBLE" 的情况 这里用一个flag标记 记录所并的节点 只有flag = n时才能成功 负责就 "IMPOSSIBLE" 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring&g

最小生成树--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

最小生成树 kruskal算法简介

生成树--在一个图中的一个联通子图  使得所有的节点都被(访问) 最小生成树 (MST) 即联通子图的总代价(路程)最小 已知的一个图 有n个点 m条边 kruskal的算法如下 先对边从小到大排序 从最小的边起,不停的合并这条边的两个节点到一个集合,如果这条边的两个节点已经在一个集合里,则无视,否则形成回路(显然错误)直到所有的节点并到一个集合里 这里需要用到并查集来合并节点 1 int cmp(const int i,const int j) { 2 return w[i] < w[j];

最小生成树 Kruskal算法

Kruskal算法 1.概览 Kruskal算法是一种用来寻找最小生成树的算法,由Joseph Kruskal在1956年发表.用来解决同样问题的还有Prim算法和Boruvka算法等.三种算法都是贪婪算法的应用.和Boruvka算法不同的地方是,Kruskal算法在图中存在相同权值的边时也有效. 2.算法简单描述 1).记Graph中有v个顶点,e个边 2).新建图Graphnew,Graphnew中拥有原图中相同的e个顶点,但没有边 3).将原图Graph中所有e个边按权值从小到大排序 4)

最小生成树 Prim算法 Kruskal算法

最小生成树 给定一个无向图,如果它的某个子图中任意两个顶点都互相连通并且是一棵树,那么这棵树就叫做生成树,如果边上有权值,那么使得边权和最小的生成树叫做最小生成树. 常见的求解最小生成树的算法有Kruskal算法和Prim算法,生成树是否存在和图是否连通是等价的,所以假定图是连通的. Prim算法 假设有一棵只包含一个顶点v的数T,然后贪心地选取T和其他顶点之间相连的最小权值的边,并把它加到T中.不断进行这个操作,就可以得到最小生成树了(可用反证法证明) 不使用Heap优化的代码 int eg[

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算法

最小生成树: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算法

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