HDU 1875 畅通工程

本文介绍了一种基于最小生成树算法解决特定问题的方法。通过忽略边长小于10或大于1000的情况,并最终检查生成树是否包含N-1条边来确保正确性。使用C++实现该算法,包括Kruskal算法的具体步骤。

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

解题思路:

依旧是最小生成树,如果边长小于10或大于1000就跳过,最后看生成树是不是有N - 1条边。

#include <iostream>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cmath>
#include <vector>
#include <queue>
#include <map>
#include <set>
#include <stack>
#define LL long long
#define FOR(i,x,y) for(int i=x;i<=y;i++)
#define rFOR(i,x,y) for(int i=x;i>=y;i--)
using namespace std;
const int maxn = 100 + 10;
struct Point
{
	double x , y;
}P[maxn];
int N , M;
double get_dis(const Point& A , const Point& B)
{
	double x = A.x - B.x;
	double y = A.y - B.y;
	return sqrt(x * x + y * y);
}
struct Edge
{
	int u;
	int v;
	double w;
	bool operator < (const Edge& rhs) const
	{
		return w < rhs.w;
	}
}e[maxn * maxn];
int f[maxn];
int find(int x)
{
	return f[x] == x ? x : f[x] = find(f[x]);
}
void Kruskal()
{
	sort(e , e + M);
	FOR(i,1,N) f[i] = i;
	double ans = 0 ; int n = 0;
	for(int i = 0 ; i < M ; i ++)
	{
		if(e[i].w < 10 || e[i].w > 1000) continue;
		int x = find(e[i].u);
		int y = find(e[i].v);
		if(x != y)
		{
			f[x] = y;
			ans += e[i].w;
			n++;
		}
	}
	if(n == N-1) printf("%.1lf\n",ans*100);
	else printf("oh!\n");
}
int main()
{
	int T;
	scanf("%d",&T);
	while(T--)
	{
		scanf("%d",&N);M = 0;
		FOR(i,1,N) scanf("%lf%lf",&P[i].x , &P[i].y);
		FOR(i,1,N)
		{
			FOR(j,i+1,N)
			{
				double dis = get_dis(P[i] , P[j]);
				e[M].u = i;
				e[M].v = j;
				e[M++].w = dis;
			}
		}
		//for(int i=0;i<M;i++) cout<<e[i].u<<' '<<e[i].v<<' '<<e[i].w<<endl;
		Kruskal();
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值