[SCOI2012]滑雪 (最小生成树 Kruskal)

题目描述

a180285非常喜欢滑雪。他来到一座雪山,这里分布着M条供滑行的轨道和N个轨道之间的交点(同时也是景点),而且每个景点都有一编号i(1iN)和一高度Hi。a180285能从景点ii滑到景点j当且仅当存在一条i和j之间的边,且i的高度不小于j。 与其他滑雪爱好者不同,a180285喜欢用最短的滑行路径去访问尽量多的景点。如果仅仅访问一条路径上的景点,他会觉得数量太少。于是a180285拿出了他随身携带的时间胶囊。这是一种很神奇的药物,吃下之后可以立即回到上个经过的景点(不用移动也不被认为是a180285 滑行的距离)。请注意,这种神奇的药物是可以连续食用的,即能够回到较长时间之前到过的景点(比如上上个经过的景点和上上上个经过的景点)。 现在,a180285站在11号景点望着山下的目标,心潮澎湃。他十分想知道在不考虑时间胶囊消耗的情况下,以最短滑行距离滑到尽量多的景点的方案(即满足经过景点数最大的前提下使得滑行总距离最小)。你能帮他求出最短距离和景点数吗?

输入格式:

输入的第一行是两个整数N,M。

接下来1行有N个整数Hi,分别表示每个景点的高度。

接下来M行,表示各个景点之间轨道分布的情况。每行3个整数Ui,Vi,Ki。表示编号为Ui的景点和编号为Vi的景点之间有一条长度为Ki的轨道。

输出格式:

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

题解:

对于高度不同的两点,他们之间的边是有向的,对于同于高度的点,有边就可以互相到达,我们只需要选取最短的一些边使他们仍联通即可。

若按照正常思路,以边权排序,直接跑Kruskal的话,会发现可能出现有下面的点连接上面的点,如:他会直接选取两条边权为5的边

 

 

 我们考虑如何消除高度的影响,我们以终点高度为第一关键字,边权为第二关键字排序,那么就不可能出现上面的情况,因为他会先选20的边。

相当于选点是逐层进行的,上面的点一定会先被选取,所以这个点选了之后,不可能再连一条向上的边。

接着愉快地打出了代码。

#include<bits/stdc++.h>
using namespace std;
#define ll long longconst int maxn=1000005;
int n,m;
ll ans;
int fa[maxn],h[maxn];
struct edge{int x,y;ll k;
}a[maxn];template<class T>inline void read(T &x){x=0;char ch=getchar();while(!isdigit(ch)) ch=getchar();while(isdigit(ch)) {x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
}void swap(ll &x,ll &y){ll t=x;x=y;y=t;}bool cmp(edge a,edge b){if(h[a.y]==h[b.y]) return a.k<b.k;return h[a.y]>h[b.y];
}int find(int x){if(fa[x]==x) return x;return fa[x]=find(fa[x]);
}void kruskal(){sort(a+1,a+m+1,cmp);int k=0;for(int i=1;i<=m;i++){int dx=find(a[i].x),dy=find(a[i].y);if(dx!=dy){fa[dx]=dy;ans+=a[i].k;k++;}if(k==n-1) break;;}printf("%d %lld",k+1,ans);
}int main(){read(n);read(m);for(int i=1;i<=n;i++) read(h[i]),fa[i]=i;for(int i=1;i<=m;i++){int x,y,z;read(x);read(y);read(z);if(h[x]<h[y]) swap(x,y);a[i]=(edge){x,y,z};}kruskal();
}
View Code

然后。。。。。

我们会发现是什么没考虑到呢?接着便可以发现可能有出发点达不到的地方,这些地方是没用的。

那么就可以考虑记录1可以利用的边,用这些边跑Kruskal。在最初读入时对于高度不同的点建有向边

高度相同建双向边,跑一边dfs,要判断是否遍历过

#include<bits/stdc++.h>
using namespace std;
#define ll long longconst int maxn=1000005;
int n,m,_n=1,cnt;
ll ans;
int fa[maxn],h[maxn];
bool vis[maxn];
vector<pair<int,ll> >e[maxn];
struct edge{int x,y;ll k;
}a[maxn];template<class T>inline void read(T &x){x=0;char ch=getchar();while(!isdigit(ch)) ch=getchar();while(isdigit(ch)) {x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
}void swap(ll &x,ll &y){ll t=x;x=y;y=t;}bool cmp(edge a,edge b){if(h[a.y]==h[b.y]) return a.k<b.k;return h[a.y]>h[b.y];
}int find(int x){if(fa[x]==x) return x;return fa[x]=find(fa[x]);
}void kruskal(){sort(a+1,a+cnt+1,cmp);int k=0;for(int i=1;i<=cnt;i++){int dx=find(a[i].x),dy=find(a[i].y);if(dx!=dy){fa[dx]=dy;ans+=a[i].k;k++;}if(k==_n-1) break;}printf("%d %lld",_n,ans);
}void dfs(int u,int f){for(unsigned int i=0;i<e[u].size();i++){int v=e[u][i].first;if(v==f) continue;a[++cnt]=(edge){u,v,e[u][i].second};if(!vis[v]){vis[v]=true;_n++;dfs(v,u);}}
}int main(){read(n);read(m);for(int i=1;i<=n;i++) read(h[i]),fa[i]=i;for(int i=1;i<=m;i++){int x,y,z;read(x);read(y);read(z);if(h[x]<h[y]) swap(x,y);e[x].push_back(make_pair(y,z));if(h[x]==h[y]) e[y].push_back(make_pair(x,z));}vis[1]=true;dfs(1,0);kruskal();
}
View Code

 

转载于:https://www.cnblogs.com/sto324/p/11172209.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/248522.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

来学习ansibie(1)

# ansible 批量在远程主机上执行命令 python2.7编写 ## 安装 第一步:下载epel源 shellwget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo 第二步:安装 shellyum install -y ansible ## ansible 命令格式 shellUsage: ansible <host-pattern&g…

CQYZOJ P1392 拔河问题

题目\(1\) Description 一个学校举行拔河比赛&#xff0c;所有的人被分成了两组&#xff0c;每个人必须&#xff08;且只能够&#xff09;在其中的一组&#xff0c;且两个组内的所有人体重加起来尽可能地接近. Input 第\(1\)行是一个\(n\)&#xff0c;表示参加拔河比赛的总人数…

灵活的Vue组件——原来这么简单

本篇学习目标 能够理解vue组件概念和作用能够掌握封装组件能力能够使用组件之间通信能够完成todo案例 1. vue组件 1.0_为什么用组件 以前做过一个折叠面板 需求: 现在想要多个收起展开的部分 方案1: 复制代码 代码重复 冗余不利于维护 案例用less写的样式, 所以下载 ya…

FOI冬令营 Day 3

目录 T1、签到题&#xff08;sort&#xff09;传送门 Code T2、送分题&#xff08;queue&#xff09;传送门 Code T3、简单题&#xff08;game&#xff09;传送门 Code 咕咕咕T1、签到题&#xff08;sort&#xff09; 传送门 原题&#xff1a;LOJ 2767 Code //2019/2/14 //50…

委托事件观察者模式

委托的默认返回类型&#xff1a;void 声明委托的关键字&#xff1a;delegate 多播委托&#xff1a;将多个方法绑定到一个委托变量 在调用方法时 可以执行绑定的方法 委托的描述&#xff1a; 委托是一个类 定义了方法的类型 可以将方法当做另一个方法进行传递 委托并不等同于方法…

赢在CSDN——名利兼收

文章目录&#x1f30a; 相识CSDN&#x1f30a; 益于CSDN流量将成为你我的亮点我的专栏收益到账啦学习会员助你拿捏专栏更多曝光自己的机会CSDN问答为你准备的零花钱&#x1f30a; 忠于CSDN&#x1f30a; 相识CSDN 小编自注册CSDN至今两年有余&#xff0c;记得初衷也仅仅是为了…

124angular1实现无限表单(仅供自己看)

//将本行的内容对象作为参数&#xff0c;传给点击函数&#xff0c;点击函数向后台发送请求&#xff0c;把获取的返回值作为内容对象的一个属性。 (function (angular) {angular.module(myModule, []).directive(treeModel, [$compile, function ($compile) {return {restrict: …

了解 Vue SSR 这一篇足以

文章目录1 - 什么是服务器端渲染&#xff1f;1.1 新建server文件夹1.2 生成一个node项目1.3 安装express1.4 服务端渲染小案例1.5 运行查看效果1.6 打开浏览器1.7 右键查看源代码2 - 什么是客户端渲染&#xff1f;2.1 新建client文件夹2.2 生成一个vue项目2.3 安装依赖并启动2.…

3 数组中的重复数字

题目描述 在一个长度为 n 的数组里的所有数字都在 0 到 n-1 的范围内。数组中某些数字是重复的&#xff0c;但不知道有几个数字是重复的&#xff0c;也不知道每个数字重复几次。请找出数组中任意一个重复的数字。 Input: {2, 3, 1, 0, 2, 5}Output: 2 思路 给出了长度为n且数组…

小型软件项目开发流程探讨

一&#xff0e;导言国内很多项目都是小型项目, 参与人员少(两到五个人), 要快速交付(一两个月) . 要成功完成这种项目, 除了使用成熟且被团队成员熟练使用的技术之外, 有一个良好的开发流程, 也是很必要的. 二&#xff0e;小型软件项目开发流程下图是我对小型软件项目开发流程…

Vue2的核心原理剖析

✨ 用了这么久的Vue2了你真的 知其然&#xff0c;知其所以然么&#xff1f; ✨今天博主就为大家带来一篇对Vue核心功能的部分剖析\textcolor{pink}{今天博主就为大家带来一篇对Vue核心功能的部分剖析}今天博主就为大家带来一篇对Vue核心功能的部分剖析 ✨后续文章会用更多小案…

Scrum之成败——从自身案例说起,仅供参考

从07年中初次接触Scrum的概念到其中几年项目中逐渐实践CI、TDD&#xff0c;到亲自掌握项目实践Scrum近一年&#xff0c;最终我们放弃了Scrum这个框架和所谓的“自组织”。原因为何&#xff1f; 1.成员放弃了Scrum所“赋予”的“权利” 比如领用任务、评估工作量、自组织协作、决…

sanic官方文档解析之下载和Configuration

1,sanic框架是做什么的? sanic的官方网址:https://sanic.readthedocs.io/en/latest/sanic框架是一个类似于flask框架的在Python3.5以上版本的文本服务器,他能够快速的编写,它是通过惊人的开发效率完成开发,希望通过这篇文章得到激励sanic框架的理念是:简单,高效 sanic的应用如…

首秀 Express 框架

文章目录框架特性express的使用初始化项目&#xff1a;下载框架模块&#xff1a;测试代码&#xff1a;总结以上代码&#xff1a;请求处理的中间件概念&#xff1a;中间件——app.use基本用法&#xff1a;next的用法app.use中间件的应用路由的保护网站维护公告自定义404&#xf…

云原生技能树测评

前言 利用午休后的10多分钟时间&#xff0c;看了看APP的技能树板块&#xff0c;简单的提出几个看法&#xff01; 答题过程 可以设置为闯关类型&#xff0c;答对一道后可以进入下一关&#xff0c;或者是一个章节为一关&#xff0c;让大家一直有一种期待 回答错误数量 可以…

原型和闭包

原型和闭包 一切皆对象 一切皆对象&#xff08;类型值除外&#xff09; undefined, number, string, boolean属于简单的值类型 函数、数组、对象、new Number(10)都是对象。他们都是引用类型 Null是基本数据类型&#xff0c;不是引用数据类型 基本数据类型的值就是它本身的值&a…

python 排序算法

冒泡排序&#xff1a; 1 #coding:utf-82 3 比较相邻的元素&#xff0c;每一趟交换后&#xff0c;最后的元素是最大的。4 第一次比较n-1次&#xff0c;第二次比较n-2次。。。第n-1次比较1次5 进行n-1次冒泡次数6 最优时间复杂度O(n),最坏时间复杂度O(n^2)7 8 9 def bubble_sort…

奖励 CSDN 社区的领军人物

设计动机 领军人物榜单在这里&#xff1a;https://blog.csdn.net/rank/list/role CSDN 是中国 IT 人士学习、成长、成功的平台&#xff0c; 这个平台有很多博主&#xff0c; 博主写的很多优秀文章获得了粉丝。 那么&#xff0c; 博主获得粉丝之后&#xff0c; 博主以粉丝为荣…

一文教会你何为重绘、回流?

文章目录css图层图层创建的条件重绘(Repaint)回流触发重绘的属性触发回流的属性常见的触发回流的操作优化方案requestAnimationFrame----请求动画帧写在最后学习目标&#xff1a; 了解前端Dom代码、css样式、js逻辑代码到浏览器展现过程了解什么是图层了解重绘与回流了解前端层…

mockjs中的方法(三)

1&#xff09;Mock.mock()&#xff1b; Mock.mock( url, type, template, function(options) ); 其中 url 是定义我们要请求的 url 地址&#xff0c;以便于我们请求的时候 mock 去进行拦截&#xff0c;知道我们要去请求那个值&#xff1b;但是它也是可选的&#xff0c;而且格式…