思路:求最小生成树无非是两种思路,用prim()算法或者克鲁斯算法。prim算法就是对一棵先拆成每个独立的点,随便找到一个点,然后比较与该点相连的所有点中权值最小的,然后把该权值加入到一个用来你保存最小生成树中的权值,然后把点加入到用来保存已选取点的数组,并对该顶点做一个标记,表示该顶点已经加入到数组中,再选取该顶点中与它相连顶点中权值最小的,以此类推。若是某个顶点与它所有相连的顶点都已经添加进去了,在剩下的顶点中选取一个顶点重新操作就好了。 由此可见,prim算法主要是根据顶点来选出最小生成树。 但是克鲁斯算法则是根据边的权值来确定的,在所有边中选取权值最小的,然后确定它的顶点,把权值跟两端的顶点分别添加到数组中,继续选权值最小的,继续添加顶点,判断是否已经存在于里面了,如果已经存在,自然是不用添加的。以此类推,直到把无向图连通,生成树就选出来了
#include<iostream>
using namespace std;#define inf 1<<29
#define max 101
int map[max][max];
int n;
void prim() //构造最小生成树
{
int i, j;
int d[max]; //用来存储权值
int mi;//用来表示当前最小的
int vis[max];//用来存储选出来的顶点
int v;//表示当前结点
for ( i = 1; i <= n; i++)
{
d[i] = map[1][i]; //把矩阵中第一行的所有值传入d数组中
vis[i] = 0; //对所有已选中的结点初始化
}
for (i = 1; i <= n; i++)
{
mi = inf;//设定一个最小值
for (j = 1; j <= n; j++)
{
if (!vis[j] && d[j]< mi)//找出与第i个顶点有联系的所有路径中最小的一条
{
mi = d[j];//找到一个路径最小的长度
v = j; //把当前最小的权值的位置记录下来
}
}
vis[v] = 1;//标记某个顶点已经存在于保存选中的顶点数组中
for (j = 1; j <= n; j++)
{
if (!vis[j] && d[j]> map[v][j])//如果某个顶点不存与选中的数组中,且初始化给定的权值至少大于至少该顶点与其他顶点相连中的权值
{
d[j] = map[v][j];//更新当前位置的权值
}
}
}
for (d[0] = 0, i = 1; i <=n; i++)//把所有选出的权值求和
{
d[0] += d[i];
}
cout << d[0] << endl;
}
int main()
{
int i, j;//只是下标
while (cin>>n)
{
//利用一个矩阵存储所有的权值
for (i = 1; i <= n; i++)
{
for (j = 1; j <= n; j++)
{
cin >> map[i][j];
}
}
prim(); //调用prim()
}
system("pause");
return 0;
}
-------------------------------
克鲁斯卡尔算法
#include<iostream>
using namespace std;
int map[101][101];
int father[10001];
int find(int x)
{
int r = x;
while (r != father[r])
r = father[r];
int temp;
while (r != x)
{
temp = father[x];
father[x] = r;
x = temp;
}
return r;
}
void merge(int x, int y)
{
father[x] = y;
}
int main()
{
int n;
while (cin >> n)
{
int i, j, k;
//memset(visited,0,sizeof(visited));
for (i = 0; i <= n*n; i++)
father[i] = i;
memset(map, 0, sizeof(map));
for (i = 0; i<n; i++)
for (j = 0; j<n; j++)
scanf("%d", &map[i][j]);
int x, y;
int sum = 0;
int fx, fy;
for (i = 1; i<n; i++)
{
int min = 1000000;
for (j = 0; j<n; j++)
for (k = j; k<n; k++)
{
if (map[j][k]<min)
{
x = find(j);
y = find(k);
// cout<<x<<" "<<y<<endl;
if (x != y)
{
// cout<<"x:"<<x<<" "<<"y:"<<y<<endl;
min = map[j][k];
fx = x;
fy = y;
//merge(x,y);
}
}
}
merge(fx, fy);
// cout<<"min:"<<min<<endl;
sum += min;
}
cout << sum << endl;
}
return 0;
}