最小生成树
问题描述
求一个连通无向图的最小生成树的代价(图边权值为正整数)。
输入
第一行是一个整数N(1<=N<=20),表示有多少个图需要计算。以下有N个图,第i图的第一行是一个整数M(1<=M<=50),表示图的顶点数,第i图的第2行至1+M行为一个M*M的二维矩阵,其元素ai,j表示图的i顶点和j顶点的连接情况,如果ai,j=0,表示i顶点和j顶点不相连;如果ai,j>0,表示i顶点和j顶点的连接权值。
输出
每个用例,用一行输出对应图的最小生成树的代价。
样例输入
1
6
0 6 1 5 0 0
6 0 5 0 3 0
1 5 0 5 6 4
5 0 5 0 0 2
0 3 6 0 0 6
0 0 4 2 6 0
样例输出
15
题解:利用kruskal算法
1.用一个结构题保存开始位置、结束位置以及距离。
2.按距离排序
3.用一个数组保存n个顶点的值。
例如第一个:序号 1 0,2,1;定义一个sum ,sum加上当前的距离。
第二个:序号 2 3,5,2,sum继续加当前的距离。
第三个:序号3 1,4,3, sum继续加当前距离。
第四个:序号4 2,5,4 。。。。。
第五个:序号 5 ,0和3一样不要交换。
第六个:序号6, 1 ,2,5
当数组里面的值都一样,就可以不用再做了。
code:
/************************************************************************/
/* 最小生成树 Kruskal算法 */
/************************************************************************/
#include <iostream>
#include <algorithm>
using namespace std;
struct MST
{
int start;
int end;
int length;
};
bool cmp(MST a,MST b)
{
if(a.length<b.length)
return true;
else
return false;
}
int main()
{
int t,n,i,j,x,k,p;
cin>>t;
while(t--)
{
k=0;
cin>>n;
MST mst[1000];
int path[1000],sum=0;
for(i=0; i<n; i++)
{
path[i] = i;
}
for(i=0; i<n; i++)
{
for(j=0; j<n; j++)
{
cin>>x;
if(i<=j)
{
if(x!=0)
{
mst[k].start = i;
mst[k].end=j;
mst[k++].length = x;
}
}
}
}
//排序
sort(mst,mst+k,cmp);
for(i=0; i<k; i++)
{
//如果前面的后面的不相同,就用后面的覆盖前面的。
if(path[mst[i].start] != path[mst[i].end])
{
int start = path[mst[i].start],end =path[mst[i].end] ;
for(p=0; p<n; p++)
{
if(path[p]==start)
{
path[p] = end;
}
}
sum+=mst[i].length;//保存距离
}
}
cout<<sum<<endl;
}
return 0;
}