当前位置: 首页 > news >正文

算法题(237):滑雪

审题:
本题需要我们找到从1号景点开始滑雪所能经过的最多景点数,以及经过最多景点时最小的滑雪路径和

思路:
方法一:dfs+kruskal算法

题意:

1.起点是1号节点

2.一共有n个节点,m条边

3.滑雪时只能从高处往下滑或者平着滑

4.由于有时间胶囊,所以可以无代价回溯节点

目标:

1.找到能经过的最多景点数

2.经过最多景点时最小的滑雪路径和


dfs深度优先遍历

由于可以无条件回溯节点,所以我们可以使用dfs遍历寻找到所有从1号节点出发能到达的节点,从而解决目标1

kruskal算法

目标2的意思是让我们找到"最小生成树",从而将最小路径和求出。本题不是真正意义上的最小生成树,因为滑雪方向有限制,有些方向是不能通过的,不是无向图


解题:
(1)数据初始化

#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
const int N = 1e5 + 10, M = 2e6 + 10;
int n, m;
ll cnt, ret,pos;
int f[N],h[N];
bool st[N];
vector<pii> edges[M];//用于存储初始图
struct edge//用于存储纳入考虑的边
{int x, y, z;
}e[M];

关键1:要存储初始图以及kruskal算法使用的图

由于给定的图不一定是连通图,所以不是所有的边都要纳入kruskal算法的考量的,那么我们就需要先存储初始图,然后在dfs中再将从1号节点出发可以经过的边存储起来并提供给kruskal计算

(2)main函数

int main()
{cin >> n >> m;for (int i = 1; i <= n; i++) cin >> h[i];for (int i = 1; i <= m; i++){int a, b, c; cin >> a >> b >> c;//按照高度判断是否可以建立边if (h[a] >= h[b]) edges[a].push_back({ b,c });if (h[a] <= h[b]) edges[b].push_back({ a,c });}dfs(1);cout << cnt << " ";kruskal();cout << ret << endl;return 0;
}

关键2:初始图边的记录

1.a高于b:存储a->b的边

2.a等于b:存储a->b的边,b->a的边

3.b高于a:存储b->a的边

所以我们用两个if语句进行判断,并进行图的存储

(3)dfs

//dfs查找从1号节点可以到达的所有边,并求出最多可到达的节点数
void dfs(int num)
{cnt++;st[num] = true;for (auto& f : edges[num]){pos++;e[pos].x = num, e[pos].y = f.first, e[pos].z = f.second;if (!st[f.first]) dfs(f.first);}
}

每次进入dfs就相当于进入了一个新的节点,负责记录节点数的cnt++,并修改节点状态

然后对该节点的所有能去的地方进行遍历,这些边就是kruskal需要纳入考虑的

然后如果此时遍历的节点也是没有到过,dfs该节点

(4)kruskal算法

//排序逻辑函数
bool cmp(edge& a, edge& b)
{int y1 = a.y, z1 = a.z, y2 = b.y, z2 = b.z;if (h[y1] != h[y2]){return h[y1] > h[y2];}else{return z1 < z2;}
}
//并查集find函数
int find(int num)
{return f[num] == num ? num : f[num] = find(f[num]);
}
//kruskal
void kruskal()
{//并查集初始化for (int i = 1; i <= n; i++){f[i] = i;}//排序sort(e + 1, e + 1 + pos, cmp);for (int i = 1; i <= pos; i++){int x = e[i].x, y = e[i].y, z = e[i].z;int fx = find(x), fy = find(y);if (fx != fy){ret += z;f[fx] = fy;}}
}

关键3:排序逻辑

由于这里不是无向图,我们如果先滑到低点,就无法从低点滑到高点了,从而导致经过的点变少,故我们需要尽量先滑到较高点,若目标点高度一致,则让路径权值小的排前面

P2573 [SCOI2012] 滑雪 - 洛谷

http://www.dtcms.com/a/500117.html

相关文章:

  • MQTT 协议深度学习笔记(含实战示例・完整版)
  • 工程建设网站导航图珠海建网站价格
  • 做外贸是什么网站网络宣传网站建设制作
  • 网站关键词制作《电子商务网站开发与管理》书籍
  • 成绩查询系统网站开发怎么做网站的图片跳转
  • 基于 GEE MODIS 数据实现 7 大遥感指数计算与可视化
  • 【计算机算法设计与分析】分治算法
  • CSS核心概念全解析:从入门到精通
  • 公司品牌网站建设常州语言网站建设
  • 北京做商铺的网站网站建设及域名申请 厦门
  • 微网站制作软件无版权视频素材网站
  • 深圳外贸建站模版那些市区做网站群
  • 【Linux】路劲解析-简析inode和dentry关系
  • AI Agent概念 原理 实践
  • 微信公众号的网站开发四川建设厅官方网站文件下载
  • 提供五屏网站建设深圳外贸建站网络推广价格
  • 电脑的 wifi 图标不见了该怎么处理
  • 深入浅出:SQL注入中的逗号绕过技巧剖析
  • (Kotlin高级特性四)kotlin属性委托(如 by lazy) 的原理?
  • 网站美术视觉效果布局设计在线服务平台的跨境电商有哪些
  • k8s(七)pod的配置资源管理
  • 做软件跟网站哪个难沭阳找做网站合伙
  • 智元灵犀X1开源分析-通讯架构
  • 5.1元挂逼VPSW
  • 旅游电子商务网站建设长春做网站wang
  • 智能语义搜索核心算法:全链路技术解析与工程实践,将rag向量检索准确率提升到98%以上……
  • 2025基于springboot的校车预定全流程管理系统
  • 学网站建设需要下载什么太平保险网站
  • 封面型网站首页怎么做做吃穿住行网站
  • macos安装、更新、使用homebrew