Original: http://www.cnblogs.com/Veegin/archive/2011/04/29/2032388.html
Note: This blog post is clear-minded, the code is concise, it is worth learning, hereby mark
Today from the Chi-right brother learned the smallest spanning tree. The so-called spanning tree is a graph of n points that are connected to n-1 bars. The minimum spanning tree is the minimum value of the sum of weights (the value of a line between two points).
First, a two-dimensional array is used to record points and weights. As shown in the No-show diagram:
int map[7][7];
map[1][2]=map[2][1]=4;
map[1][3]=map[3][1]=2;
......
The minimum spanning tree is then asked. The specific methods are:
1. Select a point as the starting point, then choose the point with the lowest weight near it (if there are multiple points with the same minimum weight attached to it, choose one of them randomly). such as 1 as a starting point.
Visited[1]=1;
Pos=1;
Use low[] Array to constantly refresh the minimum weight, low[i] (0<i<= points) The value is: I point to the nearest point (not marked) the minimum distance.
low[1]=0; The minimum distance from the starting point I to the nearest point is 0
low[2]=map[pos][2]=4;
low[3]=map[pos][3]=2;
low[4]==map[pos][4]=3;
Low[5]=map[pos][5]=maxint; No direct access
Low[6]=map[pos][6]=maxint;
2. At the extension point, find the point with the lowest value of the two adjacent to it.
low[] Update with 3 as the current position
Visited[3]=1;
pos=3;
low[1]=0; Flagged, not updated
low[2]=map[1][2]=4; Smaller than 5, not updated
low[3]=2; Flagged, not updated
low[4]=map[1][4]=3; Greater than 1, after the update: low[4]=map[3][4]=1;
low[5]=map[1][5]=maxint;//not accessible, not updated
low[6]=map[1][6]=maxint;//bigger than 2, after the update: low[6]=map[3][6]=2;
3. Such analogy ...
When all points are combined, the result is the most spanning tree as shown.
The sum of the ownership values is the minimum spanning tree with a value of 2+1+2+4+3=12.
As to how the specific code is implemented, it is now explained in conjunction with POJ1258 examples. The code is as follows:
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657 |
#include <stdio.h>
#include <string.h>
#define MaxInt 0x3f3f3f3f
#define N 110
//创建map二维数组储存图表,low数组记录每2个点间最小权值,visited数组标记某点是否已访问
int
map[N][N],low[N],visited[N];
int
n;
int prim()
{
int
i,j,pos,min,result=0;
memset
(visited,0,
sizeof
(visited));
//从某点开始,分别标记和记录该点
visited[1]=1;pos=1;
//第一次给low数组赋值
for
(i=1;i<=n;i++)
if
(i!=pos) low[i]=map[pos][i];
//再运行n-1次
for
(i=1;i<n;i++)
{
//找出最小权值并记录位置
min=MaxInt;
for
(j=1;j<=n;j++)
if
(visited[j]==0&&min>low[j])
{
min=low[j];pos=j;
}
//最小权值累加
result+=min;
//标记该点
visited[pos]=1;
//更新权值
for
(j=1;j<=n;j++)
if
(visited[j]==0&&low[j]>map[pos][j])
low[j]=map[pos][j];
}
return
result;
}
int
main()
{
int
i,v,j,ans;
while
(
scanf
(
"%d"
,&n)!=EOF)
{
//所有权值初始化为最大
memset
(map,MaxInt,
sizeof
(map));
for
(i=1;i<=n;i++)
for
(j=1;j<=n;j++)
{
scanf
(
"%d"
,&v);
map[i][j]=map[i][j]=v;
}
ans=prim();
printf
(
"%d\n"
,ans);
}
return
0;
}
|
Thanks to the teaching of Chi-right brother here!
Minimum spanning Tree prim algorithm