#102-[最小生成树]Kerry的电缆网络

这篇博客介绍了Kerry如何使用有限长度的电缆线在土鲁齐亚埃萨亚克斯乌托斯邦建立电缆网络,以连接所有城镇。问题转化为找到覆盖所有城镇的最小生成树,通过解决这个问题,确定Kerry是否能完成任务以及最少需要多少长度的电缆线。文章提供了输入输出示例,并提示注意浮点数精度问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Description

Kerry 是德国的一位电缆商人。因联合国脱贫计划的邀请,他准备负责在土鲁齐亚埃萨亚克斯乌托斯邦建立电缆网络,以满足这个国家的用电需求。当然,现在土鲁齐亚埃萨亚克斯乌托斯邦没有任何电缆。已知土鲁齐亚埃萨亚克斯乌托斯邦一共有n个城镇,已经编号为1到n。其中任意两个城镇可能有一条路,也可能没有。如果两个城镇之间有一条路pi,那么这条路有一个长度si,则Kerry可以在这两个城市之间建立一条电缆线,电缆线的长度也就是这条路的长度si。

现在Kerry准备了s长的电缆线,电缆线可以任意拆断,拆断不损失任何电缆线。他需要将土鲁齐亚埃萨亚克斯乌托斯邦所有城镇都能够连入这个电缆网络。那么,Kenny能不能使用这s长度的电缆线完成这项工作;如果能够完成,那么Kerry最少耗用多少长度的电缆线呢?

Input

第一行一个正实数S;

第二行一个正整数n;

接下来一共有m行(m是个未知数),第i行有两个整数xi,yi和一个实数si,表示编号为xi个村庄和编号为yi个村庄之间有一条路,路的长度为si。

输入保证xi不等于yi,两个城镇之间不会有两条路。

Output

若能够完成(建立这样的电缆网络),则输出(其中代表最少的电缆线长度,保留两位小数):

Needmiles of cable

否则输出:

Impossible

Sample Input

100.0
4
1 2 2.0
1 3 4.2
1 4 6.7
3 4 4.0
2 4 10.0

Sample Output

Need 10.20 miles of cable

HINT

 

【注释 Hint 】

1<=n,m<=100000

第一次开float,结果玄学WA,发现原来是精度的问题,开double就A了。

#include <iostream>
#include <vector>
#include <algorithm>

#define SIZE 100001

using namespace std;

struct edge
{
	int from, to;
	double dis;
};

vector<edge> graph;
int pre[SIZE]; // 前驱

bool comp(edge a, edge b)
{
	return a.dis < b.dis;
}

int find(int x) // 找祖先
{
	return (pre[x]) ? pre[x] = find(pre[x]) : x;
}

int main(int argc, char** argv)
{
	int n, u, v, c = 1, i, prex, prey;
	double s, w, res = 0;
	
	scanf("%lf%d", &s, &n);
	while (~scanf("%d%d%lf", &u, &v, &w))
	{
		graph.push_back({u, v, w});
	}
	
	sort(graph.begin(), graph.end(), comp);
	for (i = 0; i < graph.size(); ++i) // 求最小生成树
	{
		u = graph[i].from;
		v = graph[i].to;
		w = graph[i].dis;
		prex = find(u);
		prey = find(v);
		if (prex ^ prey)
		{
			res += w;
			if ((++c == n) || (res > s))
			{
				break;
			}
			pre[prex] = prey;
		}
	}
	
	if ((c == n) && (res <= s))
	{
		printf("Need %.2f miles of cable", res);
	}
	else
	{
		printf("Impossible");
	}
	
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值