最小生成树——克鲁斯卡尔方法

 原文出自:

https://blog.csdn.net/vocaloid01/article/details/76559746

个人非常喜欢这段代码,不是特别难,但是又新学到了东西。思路还特别清晰。 给这个博主膜拜了。


有n个城市,你要把他们用隧道连起来,问最少修多少米的隧道。

 

#include<stdio.h>
#include<cstring>
#include<iostream>
#include<queue>
#include<cstring>
#include<vector>
#include<set>
#include<algorithm>
#include<cmath>
 
#define INF 0x3f3f3f3f
 
using namespace std;
 
struct D   //存边的信息 
{
	double len;
	int head,tail;
	D(int a,int b,double mid)
	{
		head = a;
		tail = b;
		len = mid;
	}
};
 
struct cmp
{
	bool operator()(D a,D b)
	{
		return a.len>b.len;
	}
};
 
int pre[105];
int flag;
double board[105][2];
int edge;
double lenth;
 
int find(int a)  //找祖先 
{
	if(pre[a] == a)return a;
	return pre[a] = find(pre[a]);
}
 
int judge(int a,int b) //判断是在一个集合 
{
	int A = find(a);
	int B = find(b);
	if(A != B)
	{
		pre[A] = B;
		return 1;
	}
	return 0;
}
 
int main()
{
	int N;
	int key = 1;
	while(scanf("%d",&N)&&N)
	{
		if(key)key--;
		else printf("\n");//注意格式 
		lenth = 0;
		for(int i=0 ; i<=N ; i++)pre[i] = i;
 
		edge = 0;
 
		priority_queue<D,vector<D>,cmp>Q;
 
		for(int i=0 ; i<N ; i++)
		{
			scanf("%lf %lf",&board[i][0],&board[i][1]);
		}
		for(int i=0 ; i<N ; i++)
		{
			for(int j=i+1 ; j<N ; j++)
			{
				double len = sqrt(pow((board[i][0]-board[j][0]),2)+pow((board[i][1]-board[j][1]),2));
				Q.push(D(i,j,len));         // 把每条边的信息计算出来然后入队 
			}
		}
		while(edge < N-1)  //找到N-1条边后结束 
		{
			D mid = Q.top();
			Q.pop();
			if(judge(mid.head,mid.tail))
			{
				edge++;
				lenth += mid.len;
			}
		}
		printf("Case #%d:\n",++flag);
		printf("The minimal distance is: %.2f\n",lenth);
	}
	return 0;
}

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值