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

洛谷 p2537 滑雪 最小生成树的利用 最小生成树在有向图中为什么不可以,在这题中为什么又可以

题目

https://www.luogu.com.cn/problem/P2573
由于变量名实在抽象,可能再过几天我自己都看不懂这个变量是什么意思了,所以我更改的更正规了一点

题目大意就是说:有好几座山,你站了一号,你只能滑倒比你低的山去看风景,然后你有药水,可以回到你前一个到的地方,或者前前一个,或者前.....前一个,简单说就是可以无限的喝这个药水
题目读完就可以很明显的发现是最小生成树了,关于最小生成树,最直观的理解就是,给一个村庄里拉一条电线,要求电可以输送到每一户人家,然后要求这个线最短

代码

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int MAXN=1000005;
int n,m,h[MAXN],fa[MAXN];
bool vis[MAXN];
struct Edge{int u,v,w;
};
vector<Edge>all_edges;
vector<pair<int,int>>adj[MAXN];
int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);}
int bfs(){int cnt=0;queue<int>q;q.push(1);vis[1]=true;while(!q.empty()){int u=q.front();q.pop();cnt++;for(auto&edge:adj[u]){if(!vis[edge.first]){vis[edge.first]=true;q.push(edge.first);}}}return cnt;
}
signed main(){ios::sync_with_stdio(false);cin.tie(0);cin>>n>>m;for(int i=1;i<=n;i++){cin>>h[i];fa[i]=i;}for(int i=0;i<m;i++){int u,v,w;cin>>u>>v>>w;if(h[u]>=h[v]){adj[u].push_back({v,w});all_edges.push_back({u,v,w});}if(h[v]>=h[u]){adj[v].push_back({u,w});all_edges.push_back({v,u,w});}}int maxx=bfs();sort(all_edges.begin(),all_edges.end(),[](const Edge&a,const Edge&b){if(h[a.v]!=h[b.v])return h[a.v]>h[b.v];return a.w<b.w;});int minn=0;for(auto&e:all_edges){if(!vis[e.u])continue;int rootU=find(e.u),rootV=find(e.v);if(rootU!=rootV){fa[rootV]=rootU;minn+=e.w;}}cout<<maxx<<" "<<minn<<endl;return 0;
}

代码详解:

bfs部分

int bfs(){int cnt=0;queue<int>q;q.push(1);vis[1]=true;while(!q.empty()){int u=q.front();q.pop();cnt++;for(auto&edge:adj[u]){if(!vis[edge.first]){vis[edge.first]=true;q.push(edge.first);}}}return cnt;
}
这个就是最经典的bfs了,唯一要注意的就是bfs过程中的那个vis数组的记录,这个是对后面有帮助的,因为,你把高度差合法的边都读到all_edges进去了,但是,有些边你可能根本就到不了
我举个例子:
你站在1号点也就是题目要求的起点,是100 迷
2-3是300->200 也就是说2->3这个路线是可行的,这个是会被读到all_edges里面去的,但是,你的起点是1,你根本就到不了2号处,也就说你后面用kruskal来求最小生成树的时候,这个边就不应该出现在all_edges里面
但是你把它读进来了,这就会导致结果是偏大的,所以这vis数组就起作用了

建立边

for(int i=0;i<m;i++){int u,v,w;cin>>u>>v>>w;if(h[u]>=h[v]){adj[u].push_back({v,w});all_edges.push_back({u,v,w});}if(h[v]>=h[u]){adj[v].push_back({u,w});all_edges.push_back({v,u,w});}}

排序

排序环节在kruskal算法中是必要的,但是这里先按照高度排序,再按照经典的边的权值排序,为什么要按照高度先排个序呢?这个是这道题的重点(我是这么认为的)
首先,kruskal是不可以用于有向图的,它只能用于无向图,其实最小生成树这个概念就是给无向图的,有向图的那个叫最小树形图
我举个例子
2->1 边长是1
3->2 边长是2
1->2 1000
1>3  1000
如果是用kruskal的话,经过排序之后会选第一条边和第二条边,然后123都在并查集中了,在kruskal眼中,任务已经完成了,但是有向图中,就这两条边根本不可以足以建立起123之间的联通,因为甚至从1出发哪里都去不了,因为这是个有向图
同理,对于prim,我也举个例子
1->2 10
3->2 1
1->3 100
如果用prim,结果是110 (先选1->2,再选1->3)但是真正的这个有向图的结果应该是101那么,这个题也是个有向图啊,为什么这里就可以用?
就是因为这个按照高度排序,我们按照高度排序后,想要知道这个经过这些景点最少的路线,其实就是一个简单的贪心,因为路线肯定是从高到低,用kruskal的方法,当这些点被包裹进一个并查集的时候,就肯定可以满足
不会出现上面的例子就是并查集把点包括进去结果不满足条件的情况
sort(all_edges.begin(),all_edges.end(),[](const Edge&a,const Edge&b){if(h[a.v]!=h[b.v])return h[a.v]>h[b.v];return a.w<b.w;});

经典kruskal

int minn=0;for(auto&e:all_edges){if(!vis[e.u])continue;//这个vis就是在这里发挥作用的,如果这条边不可达,那就不用kruskal,答案就不会偏大int rootU=find(e.u),rootV=find(e.v);if(rootU!=rootV){fa[rootV]=rootU;minn+=e.w;}}
http://www.jsqmd.com/news/751230/

相关文章:

  • OpenWrt包管理深度解析:手把手教你制作一个能上menuconfig的软件包(以日志服务为例)
  • Mac访达( Finder )与终端(Terminal)协同办公指南:从图形界面到命令行的无缝切换
  • GTA5线上小助手:让你的洛圣都冒险更加轻松愉快
  • ComfyUI ControlNet Aux:30+预处理器一站式解决方案,AI绘画控制从未如此简单
  • 亨得利维修保养服务地址与电话全解析:为何你的百达翡丽、爱彼、劳力士只能托付给这六大城市直营门店? - 时光修表匠
  • Vue-Codemirror 技术架构深度解析与高性能集成方案
  • fre:ac音频转换器完整指南:从新手到高手的免费音频处理方案
  • F3D:跨平台高性能3D查看器的架构解析与深度集成实践
  • 破解硅胶发泡条密封失效难题:CTP定制方法论如何实现持久密封? - 速递信息
  • 告别重复造轮子:用快马ai一键生成esp8266高效开发核心模块
  • 5步开启纯净B站体验:PiliPlus开源客户端完全指南
  • 5分钟搭建专业量化交易平台:Backtrader PyQt可视化界面终极指南
  • 成都洁祥瑞保洁服务:新津开荒保洁公司推荐 - LYL仔仔
  • Playwriter语法使用总结
  • ElasticSearch集群状态红了黄了怎么办?手把手教你用Multi ElasticSearch Head插件快速定位问题
  • 魔兽争霸3终极优化伴侣:WarcraftHelper完整配置指南
  • 3步搞定Claude Code多终端同步:告别重复配置的烦恼
  • leetcode热题 - 5
  • AD9361 SPI no-os 文件移植 SoftConsole MPFS250T 初学(二) 接口适配
  • 亨得利全国7大直营服务中心维修保养地址电话全公开:百达翡丽、江诗丹顿、爱彼等高端腕表正规维修为何仅限北上广深等六城? - 时光修表匠
  • AC-3(通常指 Dolby Digital)音频解码器
  • video_to_axi_stream
  • 3分钟搞定微信语音转MP3:Silk v3解码器完全指南
  • 技术指南:Sabaki围棋软件构建专业级围棋分析与SGF编辑环境
  • day31-局部重绘视频创作
  • 厦门纹眉机构哪家靠谱?久匠连锁直营,专攻原生自然眉,长效定型超省心 - 企业博客发布
  • 在自动化脚本中如何实现文本转语音?
  • 打破语言壁垒:Translumo屏幕翻译工具让外语游戏与视频无障碍畅玩
  • 常州市涂料协会五届五次会员大会暨2026涂料行业高质量发展论坛在常州隆重召开 - 速递信息
  • 将 Hermes Agent 工具链接入 Taotoken 实现自定义模型调用