Aizu - 2224 Save your cats 最大生成树

该博客探讨了如何通过最小化边的删除成本来确保图中不存在环的问题。解决策略是构建最大生成树,从而确保剩余的边集合构成一棵树,并最大化边的权重。作者提供了相关的思考点和代码实现。

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

传送门:AOJ 2224

题意:有n个点和m条边,每条边有不同的权值,问最少花费多少删除边能使得图中没有圈。

思路:我们知道树是没有圈的,因此删边后的图一定是一棵树,我们想要删除的边权尽量小,就是要留下的边权尽量大,因此留下的树必定是最大生成树。

关键点就是思维的转化,剩下的就没什么难的了。

代码:

#include<bits/stdc++.h>
#define ll long long
#define pb push_back
#define fi first
#define se second
#define pi acos(-1)
#define inf 0x3f3f3f3f
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define rep(i,x,n) for(int i=x;i<n;i++)
#define per(i,n,x) for(int i=n;i>=x;i--)
using namespace std;
typedef pair<int,int>P;
const int MAXN=100010;
int gcd(int a,int b){return b?gcd(b,a%b):a;}
P p[MAXN];
double Dis(P &a, P &b)
{
	return sqrt((a.fi - b.fi) * (a.fi - b.fi) + (a.se - b.se) * (a.se - b.se));
}
struct node{
	int u,v;
	double w;
	node(int _u = 0, int _v = 0, double _w = 0) : u(_u), v(_v), w(_w){
	}
	bool operator < (node a) const
	{
		return w > a.w;
	}
}mp[MAXN];
int f[MAXN];
int getf(int k)
{
	return k == f[k] ? k : f[k] = getf(f[k]);
}
double kruskal(int n, int m)
{
	int i = 0, cnt = 1;
	double sum = 0;
	while(i < m && cnt < n)
	{
		int u = getf(mp[i].u);
		int v = getf(mp[i].v);
		if(u != v)
		{
			f[u] = v;
			cnt++;
			sum += mp[i].w;
		}
		i++;
	}
	return sum;
}
int main()
{
	int n, m, u, v;
	cin >> n >> m;
	for(int i = 1; i <= n; ++i)
	{
		scanf("%d %d", &p[i].fi, &p[i].se);
		f[i] = i;
	}
	double sum = 0;
	for(int i = 0; i < m; i++)
	{
		scanf("%d %d", &u, &v);
		mp[i] = node(u, v, Dis(p[u], p[v]));
		sum += Dis(p[u], p[v]);
	}
	sort(mp, mp + m);
	cout << fixed << setprecision(3) << sum - kruskal(n, m) << endl;
 	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值