hihoCoder#1097 最小生成树一·Prim算法

原题地址

 

Prime算法,每次挑选一个距离原点最近的节点,然后收缩(visited为true,设置该点到原点的距离为0)

注意:虽然Prime算法跟Dijkstra很像,但两者还是不一样的。

因为Dijkstra算法每次在挑选节点后不会收缩,所以,用Dijkstra挑选的边并不一定是最小生成树。

比如下面这张图,有a、b、c三个节点

     2

  a----b

   \   |

  3 \  | 2

     \ |

      c

求a的单源最短路径得到的图是这样的:

     2

  a----b

   \   

  3 \ 

     \ 

      c

而小生成树应该是这样的:

     2

  a----b

       |

       | 2

       |

      c

 

 

代码:

 1 #include <iostream>

 2 #include <cstring>

 3 

 4 using namespace std;

 5 

 6 #define MAX_POINT 1024

 7 

 8 int N;

 9 int g[MAX_POINT][MAX_POINT];

10 bool visited[MAX_POINT];

11 

12 int prime() {

13   int res = 0;

14   int left = N - 1;

15   visited[1] = true;

16   while (left) {

17     int k = 0;

18     for (int i = 1; i <= N; i++)

19       if (!visited[i] && g[1][i] < g[1][k])

20         k = i;

21     visited[k] = true;

22     left--;

23     res += g[1][k];

24     g[1][k] = g[k][1] = 0;

25     for (int i = 1; i <= N; i++)

26       if (!visited[i] && g[1][i] > g[1][k] + g[k][i])

27         g[1][i] = g[i][1] = g[1][k] + g[k][i];

28   }

29 

30   return res;

31 }

32 

33 int main() {

34   memset(g, 1, sizeof(g));

35   memset(visited, false, sizeof(visited));

36   scanf("%d", &N);

37   for (int i = 1; i <= N; i++)

38     for (int j = 1; j <= N; j++)

39       scanf("%d", &(g[i][j]));

40   printf("%d\n", prime());

41 

42   return 0;

43 }

 

你可能感兴趣的:(最小生成树)