算法总结——Prim

Prim:

复杂度:O(n^2)

用途:最小生成树算法,求一点到所有的位置之和的最小值,不是形成环,是把所有顶点连在一起的最短路

适用条件:

步骤:跟Dijkstra出奇的相似,只是prim把d和p都变成一个k数组(- -其实一样好吗)而且Dijkstra是第一个for为了记录下标,而prim是为了记录下标和记录最小值(- -其实也是一样好吗),不过prim的第二个for是已经确定了走了一条路,然后是从这条路出发,看从这个定点出发和原来的最短路径相比哪个短,如果从这个顶点出发的更短,那么更新k,,而Dijkstra只是单纯的把地图优化。

模板:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int inf = 0x3f3f3f3f,MAX = 3000;
int map[MAX][MAX], k[MAX];
void prim (int map[MAX][MAX],int n){
    int min1,m,ans = 0;
    for(int i = 1; i <= n ;i++)
        k[i] = map[1][i];
    for(int i = 1; i < n ;i++){
         int min1 = inf;
         m = 0;
         for(int j = 1; j <= n ;j++){
            if(k[j] < min1 && k[j]!=0){
             min1 = k[j];
             m = j;
            }
         }
         k[m] = 0;
         ans +=min1;
         for(int j = 1; j <= n ; j++){
            if(k[j] > map[m][j] && k[j]!=0)
                k[j] = map[m][j];
         }
    }
    printf("%d\n",ans);
}
int main()
{
    int n,a;
    while(~scanf("%d",&n)&&n){
            for(int i = 1; i <= n ;i++)
              for(int j = 1; j <= n ;j++)
                scanf("%d",&map[i][j]);
            prim(map,n);
    }
    return 0;
}
时间: 2025-01-10 11:57:08

算法总结——Prim的相关文章

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

最小生成树的两种算法:Prim和Kruskal算法

越来越明白了一个道理:你写不出代码的原因只有一个,那就是你没有彻底理解这个算法的思想!! 以前写过最小生成树,但是,水了几道题后,过了一段时间,就会忘却,一点也写不出来了.也许原因只有一个,那就是我没有彻底理解这两种算法. 主题: 其实,求最小生成树有两个要点,一个是权值最小,还有一个就是这个图必须是树.而Prim和Kruskal的不同之处在于两者选择的变量不同,Prim选择的是始终保持权值最小,然后逐个加点构建一棵树.而Kruskal则是始终保证是一棵树(虽然构建过程中不一定是真正的树,但并查

转 最小生成树(kruskal 算法 和prim算法)

链接:http://blog.csdn.net/weinierbian/article/details/8059129/ 给定一个带权的无向连通图,如何选取一棵生成树,使树上所有边上权的总和为最小,这叫最小生成树. 求最小生成树的算法(1) 克鲁斯卡尔算法图的存贮结构采用边集数组,且权值相等的边在数组中排列次序可以是任意的.该方法对于边相对比较多的不是很实用,浪费时间.(2) 普里姆算法图的存贮结构采用邻接矩阵.此方法是按各个顶点连通的步骤进行,需要用一个顶点集合,开始为空集,以后将以连通的顶点

图基本算法 最小生成树 Prim算法(邻接表+优先队列STL)

这篇文章是对<算法导论>上Prim算法求无向连通图最小生成树的一个总结,其中有关于我的一点点小看法. 最小生成树的具体问题可以用下面的语言阐述: 输入:一个无向带权图G=(V,E),对于每一条边(u, v)属于E,都有一个权值w. 输出:这个图的最小生成树,即一棵连接所有顶点的树,且这棵树中的边的权值的和最小. 举例如下,求下图的最小生成树: 这个问题是求解一个最优解的过程.那么怎样才算最优呢? 首先我们考虑最优子结构:如果一个问题的最优解中包含了子问题的最优解,则该问题具有最优子结构. 最小

Dijkstra算法与Prim算法辨析

这两个算法真的很像,尽管它们的用处截然不同. Dijkstra是找单源非负的最短路径. Prim是找最小生成树. Dijkstra算法都是找当前标记集合点再扩一条边所形成的最短路径,然后更新标记点集,外扩路径集. Prim是找当前标记集合点再扩一条边中所形成的的最短边,然后更新标记点集,外扩边集. 所以细节上是有不同的. Dijkstra复杂度O(N2), Prim O(eloge).

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

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

贪心算法之Prim

Prim与Dijistra算法有异曲同工之妙,只不过Dijistra是求最短路径,每次添加到集合中的是到固定起始点的最短距离,而Prim是求最小生成树,是整个图所有权重的最小和,每次添加到集合中的是到整个集合最短距离的点. Prim算法具体如下所示: 1 #include <iostream> 2 3 using namespace std; 4 5 #define INF 1e7 6 #define MAXNODE 100 7 8 bool flag[MAXNODE]; 9 int clos

最小生成树算法(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[MaxVer