- 基本思路
每次都找到不会构成回路的最小边,把这条边的结点收录 - 举例
如下图:
找到最小边1,把v1,v4收录
找到最小边1,把v6,v7收录
找到最小边2,把v2收录
找到最小边2,把v3收录
找到最小边4,
找到最小边6,把v5收录

#include <iostream>
#define MAX 11111
#define SIZE 10
int root[SIZE];
int check(int i,int j)
{
int root1,root2;
while(1)
{
if(root[i]<0)
{
root1=i;
break;
}
else{
i=root[i];
}
}
while(1)
{
if(root[j]<0)
{
root2=j;
break;
}
else{
j=root[j];
}
}
if(root1==root2)
{
return 0;
}
else
{
if(root[root1]<root[root2])
{
root[root1]+=root[root2];
root[root2]=root1;
}
else
{
root[root2]+=root[root1];
root[root1]=root2;
}
return 1;
}
}
void Kruskal(int edge[][SIZE],int n)
{
int count=0;
int v1,v2;
int tree[n][n]={0};
while(count<n)
{
int min=MAX;
v1=v2=-1;
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
if(edge[i][j]<min)
{
min=edge[i][j];
v1=i;
v2=j;
}
}
}
if(v1==-1 || v2==-1)
{
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
printf("%d ",tree[i][j]);
}
printf("\n");
}
break;
}
edge[v1][v2]=edge[v2][v1]=MAX;
if(check(v1,v2))
{
count++;
tree[v1][v2]=tree[v2][v1]=min;
}
}
}
int main(int argc, char** argv) {
int n,m;
scanf("%d %d",&n,&m);
int start,end,value;
int edge[SIZE][SIZE];
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
edge[i][j]=MAX;
}
root[i]=-1;
}
for(int i=0;i<m;i++)
{
scanf("%d %d %d",&start,&end,&value);
edge[start][end]=edge[end][start]=value;
}
Kruskal(edge,n);
return 0;
}
- 运行结果

结果代表的是新生成的最小生成树的边的情况