「SCOI2012」滑雪与时间胶囊(kruskal)

本文介绍了一道关于滑雪路径优化的问题,其中涉及到图论中的Kruskal算法。题目要求在满足最短滑行距离的同时,尽可能访问更多的景点。作者通过分析高度限制和遍历点最多的需求,提出了一种结合广度优先搜索和Kruskal算法的解决方案,最终实现对边的排序并应用Kruskal算法找到最佳路径。
摘要由CSDN通过智能技术生成

题目描述

a180285 非常喜欢滑雪。他来到一座雪山,这里分布着 m 条供滑行的轨道和 n 个轨道之间的交点(同时也是景点),而且每个景点都有一编号 i (1≤i≤n) 和一高度 h。

a180285 能从景点 i 滑到景点 j 当且仅当存在一条 i 和 j 之间的边,且 i 的高度不小于 j。与其他滑雪爱好者不同,a180285 喜欢用最短的滑行路径去访问尽量多的景点。如果仅仅访问一条路径上的景点,他会觉得数量太少。

于是 a180285 拿出了他随身携带的时间胶囊。这是一种很神奇的药物,吃下之后可以立即回到上个经过的景点(不用移动也不被认为是 a180285 滑行的距离)。

请注意,这种神奇的药物是可以连续食用的,即能够回到较长时间之前到过的景点(比如上上个经过的景点和上上上个经过的景点)。 现在,a180285站在 1 号景点望着山下的目标,心潮澎湃。他十分想知道在不考虑时间胶囊消耗的情况下,以最短滑行距离滑到尽量多的景点的方案(即满足经过景点数最大的前提下使得滑行总距离最小)。你能帮他求出最短距离和景点数吗?

输入格式

输入的第一行是两个整数 n,m。 接下来一行有 n 个整数 h
i

,分别表示每个景点的高度。

接下来 m 行,表示各个景点之间轨道分布的情况。每行三个整数 u,v,k 表示编号为 uu的景点和编号为 v 的景点之间有一条长度为 k 的轨道。

输出格式

输出一行,表示 a180285 最多能到达多少个景点,以及此时最短的滑行距离总和。

输入输出样例

输入 #1

3 3
3 2 1
1 2 1
2 3 1
1 3 10

输出 #1

3 2

分析

首先拿道题,觉得十分简单,随手写了一个近似模板的Kruskal的代码,嗯~~不错,WA 0了,于是开始仔细读题,
以最短滑行距离滑到尽量多的景点的方案。居然还要遍历的点最多,有点麻烦啊。于是,开始瞎搞。

满足高度限制

当两个顶点有边相连,找到高度大的顶点作为起点,高度小的顶点作为终点,边的长度作为距离,放进一个数组。

满足遍历的点最多

要使遍历的点最多,即得到从一开始包含最多点的图,可以写一个bfs,先将起点1压入队,然后把起点能直接到达的点继续压入,并将计数器加一下。直到已经不能找到其他可以达到的点。可以用一个结构体存储起点、终点、距离,并用一个二维vector存储结构体以便找到与之相连的点。设置一个结构体数组,当找到可以扩展的顶点时,将当时vector中的起点,终点,距离全部赋给数组,可以更好地进行下面的Kruskal。
综上所述,可以写出代码:

void bfs() {
   
	vis[1] = 1;
	jis[++numr] = 1;
	while(numl < numr) {
   
		ll f = jis[++numl];
		int Size = vec[f].size();
		for(int i = 0;i < Size;i ++) {
   
			a[++cnt].u = f;
			a[cnt].v = vec[f][i].v;
			a[cnt].w = vec[f][i].w;
			if(!vis[a[cnt].v]) {
   
				vis[a[cnt].v] = 1
  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值