克鲁斯卡尔算法的实现(找最小生成树)

天下大事,必做于细;天下难事,必作于易。
这个算法看了两天,边看边骂那一种,可今天,我先把并查集算法的代码搞懂了,结果才发现不过是排序后的元素进行并查集操作。

具体思想:将图的每条边保存下来(a:顶点,b:顶点,w:权重),a<b;
然后将按照权重大小进行边排序,(冒泡,快排,还未学到排序,所以我用的最简单的冒泡),然后将边进行合并。

具体代码如下:


// day19.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include<iostream>
using namespace std;
typedef struct road
{
	int a,b;
	int w;
}road;
typedef struct
{
	int n,e;
	int data[100][100];
}graph;
void createg(graph &g)
{
	int i,row,column,weigt;
	cout<<"请输入顶点个数,边的条数"<<endl;
	cin>>g.n>>g.e;
	for(i=0;i<g.e;i++)
	{
		cout<<"请输入边的顶点,权值"<<endl;
		cin>>row>>column>>weigt;
		g.data[row][column]=weigt;
		g.data[column][row]=weigt;
	}
}
road r[100];
void createroad(graph g,road r[])
{ 
	int i,j,num=0;
	for(i=0;i<g.n;i++)
	{
		for(j=0;j<g.n;j++)
		{
			if(g.data[i][j]!=0&&i<j)
			{
				r[num].a=i;
				r[num].b=j;
				r[num].w=g.data[i][j];
				num++;
			}
		}
	}
	for(i=0;i<num-1;i++)
	{
      for(j=0;j<num-1-i;j++)
	  {
          road a;
		  if(r[j].w>r[j+1].w)
		  {
			  a=r[j];
			  r[j]=r[j+1];
			  r[j+1]=a;
		  }
	  }
	}
}
int getroot(int a,int pre[])
{
	while(a!=pre[a])
	{
		a=pre[a];
	}
	return a;
}
void kruskal(road r[],graph g)
{
   int i,root1,root2,sum=0;
   int pre[100]={0};
   for(i=0;i<g.n;i++)
   {
	   pre[i]=i;
   }
//   for(i=0;i<g.e;i++)
 //  {
//	   cout<<r[i].a<<' '<<r[i].b<<' '<<r[i].w<<endl;
  // }
   for(i=0;i<g.e;i++)
   {
       root1=getroot(r[i].a,pre);
	   root2=getroot(r[i].b,pre);
	   cout<<root1<<' '<<root2<<endl;
	   if(root1!=root2)
	   {
		   pre[root1]=root2;
		   sum+=r[i].w;
	   }
   }
   for(i=0;i<g.n;i++)
	   cout<<pre[i]<<' ';
   cout<<"最小权值"<<sum<<endl;
   
}
int main(int argc, char* argv[])
{
	road r[100];
	graph g;
	createg(g);
	createroad(g,r);
	kruskal(r,g);
	return 0;                                                                                                                                                                      
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值