最小生成树

来源:互联网 发布:openwrt usb网络共享 编辑:程序博客网 时间:2024/06/12 00:52


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