码迷,mamicode.com
首页 > 其他好文 > 详细

hihocoder(1097) 最小生成树Prim

时间:2015-04-11 17:45:36      阅读:176      评论:0      收藏:0      [点我收藏+]

标签:

图论一直是自己算法中最最最柔弱的部分,主要是,当年数据结构的课程,后面就去打酱油了,后来时间又都花在了电赛上,平时用的相关部又少,这一部分就更弱了,总是懒得捡起来,但是现在可是没退路了,开始好好复习这一部分。

Prim算法是求解无向图最小生成树的经典算法,和Dijkstra算法类似,但是Prim算法每次获取一个新的顶点后,都有一个聚合的过程,而Dijkstra没有,并且Dijkstra的对象是有向图的单源最短路径,所以这两个算法起始本质上是不同的,然而他们的思想是一致的:贪心

刚好借着hihocoder的这个题实现一下这个算法,刚开始的时候拿STL的set和vector做的,但是由于没有用辅助数组,也没有用到聚合的思想,于是傻傻的写了个O(n3)的算法,直接超时了,用例测时,3300多ms,后来醒悟过来,明明记得Prim是O(n2)的算法,于是果断丢掉set和vector,重新试实现了下,添加辅助数组low。

总结:

Prim算法时间复杂度O(n2),适合于边比较密集的Graph。另外一个算法Kruskal的算法O(eloge),适合于边比较稀疏的情况。

Impl:

技术分享
 1 #include <iostream>
 2 #include <cstring>
 3 #include <cstdio>
 4 #include <climits>
 5 
 6 using namespace std;
 7 
 8 int w[1010][10010];
 9 int low[10010];
10 bool visited[10010];
11 int n;
12 
13 int prim()
14 {
15     int pos,min,res = 0;
16     int left = n;
17 
18     //选取任意点作为开始节点,初始化辅助数组
19     visited[0] = true; pos = 0;
20     for (int i = 0; i < n; ++i){
21         if (i != pos) low[i] = w[pos][i];
22     }
23 
24     for (int i = 1; i < n; ++i)
25     {
26         min = INT_MAX;
27         for (int j = 0; j < n; ++j) //找出收缩后的最优节点
28             if (!visited[j] && min>low[j])
29                 min = low[j], pos = j;
30 
31         res += min;
32         visited[pos] = true;
33 
34         for (int j = 0; j < n; ++j) //一个收缩的过程,刷新辅助数组
35             if (!visited[j] && low[j]>w[pos][j])
36                 low[j] = w[pos][j];
37     }
38 
39     return res;
40 }
41 
42 
43 int main()
44 {
45     scanf("%d", &n);
46     for (int i = 0; i < n; ++i)
47         for (int j = 0; j < n; ++j)
48             scanf("%d", &w[i][j]);
49     memset(visited, 0, sizeof(visited));
50 
51     printf("%d\n", prim());
52 
53     return 0;
54 }
View Code

 

hihocoder(1097) 最小生成树Prim

标签:

原文地址:http://www.cnblogs.com/sheepsheep/p/4417991.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!