最小生成树——prim算法(个人总结)
2017-02-28 12:59
375 查看
这次我写一些我对最小生成树的见解,最近做了一些这类型的题,相当于个人总结一下。
最小生成树,比如几个村庄之间给出几个每两个村庄之间需要修多长的路,然后要你选择修路方式让所有村庄连通,而且要让修路的长度最小,当然也可以对应修路的消耗。这种情况下就要用到最小生成树。
如上图所示,假设这里有A,B,C,D,E五个村庄,现在准备在这五个村庄之间修路,然后对应每两个村庄之间修路有一个需要修路的长度(也可以表示修这条路需要消耗的资源什么的),为了使五个村庄连通并且让修路长度最短。应该怎么办呢。
这时我们可以随便找一个村庄开始修路,比如从A开始,然后它可以修3条路到其他村庄,这时我们选择长度最短的AD,现在我们修了长度为4的路了,并且连通了村庄D,然后再找下一条路,也就是现在A和D村庄能够到达其他村庄的一条路,这时我们还是找最小的,也就是DC长度最短,连通村庄C,一共修路长度为7了,然后又继续找,依次寻找最短的那一条,就会再找到DE和AB,最后最小需要修路长度为17,就可以得到我们想要的结果了。
接下来是代码:
最小生成树,比如几个村庄之间给出几个每两个村庄之间需要修多长的路,然后要你选择修路方式让所有村庄连通,而且要让修路的长度最小,当然也可以对应修路的消耗。这种情况下就要用到最小生成树。
如上图所示,假设这里有A,B,C,D,E五个村庄,现在准备在这五个村庄之间修路,然后对应每两个村庄之间修路有一个需要修路的长度(也可以表示修这条路需要消耗的资源什么的),为了使五个村庄连通并且让修路长度最短。应该怎么办呢。
这时我们可以随便找一个村庄开始修路,比如从A开始,然后它可以修3条路到其他村庄,这时我们选择长度最短的AD,现在我们修了长度为4的路了,并且连通了村庄D,然后再找下一条路,也就是现在A和D村庄能够到达其他村庄的一条路,这时我们还是找最小的,也就是DC长度最短,连通村庄C,一共修路长度为7了,然后又继续找,依次寻找最短的那一条,就会再找到DE和AB,最后最小需要修路长度为17,就可以得到我们想要的结果了。
接下来是代码:
#include <stdio.h> #include <string.h> #define MAXN 1005 #define INF 0x3f3f3f3f int vis[MAXN], contact[MAXN][MAXN],dis[MAXN];//vis用来判断当前点是否已经连通,contact数组 //存放两个点间连接的长度,dis在接下来的操作中用到 int main() { int n, m, i, j, a, b, len, k, min, sum; scanf("%d%d", &n, &m); memset(contact, 0, sizeof(contact)); memset(vis, 0, sizeof(vis)); for (i = 1; i <= m; i++) { scanf("%d%d%d", &a, &b, &len); //这里要判断一下两个点间是否已经有过可以连通的路线,没有直接输入数组中 //如果有取小的那一条,但是要看题意,如果说明了两点间有且只有一条路线,那么就不用判断 if (contact[a][b] == 0) { contact[a][b] = len; contact[b][a] = len; } else if (contact[a][b] > len) { contact[a][b] = len; contact[b][a] = len; } } for (i = 1; i <= n; i++) { dis[i] = contact[1][i];//dis这里存放的是点1到其他点的距离,为0,就是没有路线 //下面的对dis的操作就是更新现在连通的点到其他点的最短距离 } vis[1] = 1; sum = 0; for (i = 1; i <= n; i++) { min = INF; for (j = 1; j <= n; j++) { if (!vis[j] && dis[j] && min > dis[j])//注意dis保存的值为0的情况 { min = dis[j]; k = j;//k保存max对应的点 } } if (min == INF) { continue;//min值没改变就证明当前连通点不能够连通其他点了 } vis[k] = 1;//连通的点进行标记 sum += min; for (j = 1; j <= n; j++) { if (!vis[j] && (contact[k][j] < dis[j] || !dis[j])&&contact[k][j])//先判断是否是已经连通的点 //然后判断dis如果为0,然后连通的路线不为0就可以直接赋值,不然就取小 { dis[j] = contact[k][j]; } } } printf("%d\n", sum); return 0; }以上便是我对最小生成树的一点理解,如有错误,欢迎指正。
相关文章推荐
- 最小生成树之Prim算法的学习心得与个人总结
- 图的最小生成树prim算法总结
- HDU1863:畅通工程2(最小生成树Kruskal算法与Prim算法)
- POJ 1789 Truck History (Prim算法求最小生成树)
- 最小生成树Prim算法模板
- 最小生成树—prim算法
- 最小生成树-Prim算法和Kruskal算法
- 最小生成树-Prim算法和Kruskal算法
- 最小生成树-Prim算法和Kruskal算法
- 18-1-30~2~5一周算法总结(DP,二分图,最小生成树)
- 算法java实现--贪心算法--最小生成树问题--Prim算法
- 最小生成树----Prim算法(邻接矩阵存图)
- HDU 1102 Constructing Roads (最小生成树 Prim算法)
- 最小生成树--prim算法(poj 2485)
- Prim算法(最小生成树)
- 最小生成树--Prim算法
- POJ 1258 Agri-Net(最小生成树prim算法)
- 最小生成树--Prim算法
- 贪婪算法在求解最小生成树中的应用(JAVA)--Prim算法
- 最小生成树(Prim算法和Kruskal算法)