洛谷 P1195 口袋的天空

引用大佬的

-------------

连的边数 得到的树的个数

n-1 1

n-2 2

n-3 3

... ...

n-k k

所以我们如果想要连出k棵树,就需要连n-k条边。

题目要求用n朵云连出k个棉花糖。

因为每个棉花糖都是连通的,

那么每个棉花糖就相当于是一棵树。

就是说要用n个节点连出k棵树。

也就是说要用n-k条边连出k棵树。

也就是说要花费连出n-k条边的代价。

既然一定要花费连出n-k条边的代价,

那么当然要选择代价最小的边连起来。

所以给每条可以连的边按代价从小到大排个序,

然后连n-k条边造k个最小生成树就可以了。

-----------------



const int N = 1e3 + 10;

LL n,m,k;
struct Edge
{
	LL a,b,w;
	bool operator< (const Edge &t) const
	{
		return w < t.w;
	}
};

LL p[N];
vector<Edge> edges;

LL find(LL x)
{
	if (p[x] != x) p[x] = find(p[x]);
	return p[x];
}

void solve()
{
	cin >> n >> m >> k;
	for (int i = 1;i <= m; i++)
	{
		LL a,b,w; cin >> a >> b >> w;
		edges.push_back({a,b,w});
	}
	
	sort(edges.begin(),edges.end());
	
	for (int i = 1;i <= n;i ++) p[i] = i;
	
	LL ans = 0;
	LL cnt = 0;
	for (auto &[a,b,w] : edges)
	{
		if (find(a) == find(b)) continue;
		ans += w;
		p[find(a)] = find(b);
		cnt ++;
		if (cnt >= n - k) break;
 	}
 	
 	if (cnt >= n - k) cout << ans << endl;
 	else cout << "No Answer" << endl;
}	




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值