最小生成树



最小生成树
问题描述
求一个连通无向图的最小生成树的代价(图边权值为正整数)。
输入
第一行是一个整数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;
}





  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值