最近在写一些数据结构的程序,看到图,所以就小结一下.
对于Prim算法,文字方面的叙述就不过多谈了,书上写的很清楚。其实很简单就是:先从一个顶点开始找与其相连的顶点的权值最小的那个,并连接在一起,在以这连个顶点分别找与其他顶点的最短权值边,找到最小的并相连:
具体看程序啦:
#include <stdio.h>
#include <stdlib.h>
#define MAX 100
#define infinity 32768
int graph[MAX][MAX];
int Prim(int graph[][MAX],int n);
int Kruskal(int graph[][MAX],int n);
int main()
{
int i,j,k,m,n;
int cost;
char chx,chy;
printf("输入节点数,边数 : ");
scanf("%d,%d",&m,&n);
getchar();
for(i = 1; i <= m; i++)
{
for(j = 1; j <= m; j++)
graph[i][j] = infinity;
}
printf("输入弧尾 弧头 及权值: \n");
for(k = 0; k < n; k++)
{
scanf("%c %c %d",&chx,&chy,&cost);
getchar();
i = chx - 'A' + 1;
j = chy - 'A' + 1;
graph[i][j] = cost;
graph[j][i] = cost;
}
// cost = Prim(graph,m);
cost = Kruskal(graph,m);
printf("Total: %d\n",cost);
return 0;
}
int Prim(int graph[][MAX],int n)
{
int end[MAX]; // end 记录以j为终点的权值
int start[MAX]; // start[i] 记录对应 end[i] 的起点 (便于输出结点)
int i,j,min,minid,sum = 0;
for(i = 2; i <= n; i++)
{
end[i] = graph[1][i];
start[i] = 1;
}
start[1] = 0; //初始化start[1]
for(i = 2; i <= n; i++)
{
min = infinity;
minid = 0;
for(j = 2; j <= n; j++)
{
if( end[j] < min && end[j] != 0 )
{
min = end[j];
minid = j;
}
}
printf("%c - %c : %d \n",start[minid] + 'A' - 1,minid + 'A' - 1,min);
sum += min;
end[minid] = 0; //minid号结点加入树
for(j = 2; j <= n; j++)
{
if( graph[minid][j] < end[j] )
{
end[j] = graph[minid][j];
start[j] = minid;
}
}
}
return sum;
}
int Kruskal(int graph[][MAX],int n)
{
int set[MAX],i,j;
int x = 1,y = 1,k = 0,min;
int sum = 0;
for(i = 1; i <= n; i++)
set[i] = i;
while( k < n - 1 )
{
min = infinity;
for(i = 1; i <= n; i++)
for(j = 1; j <= n; j++)
if(graph[i][j] < min)
{
min = graph[i][j];
x = i;
y = j;
}
sum += min;
graph[x][y] = infinity;
if(set[x] != set[y])
{
printf("%c - %c : %d \n",(x + 'A' - 1),(y + 'A' - 1),min);
k++;
for(i = 1; i <= n; i++)
if(set[i] == set[y]) //将顶点y加入到集合x中
set[i] = set[x];
}
}
return sum;
}