bzoj1975: [Sdoi2010]魔法猪学院

树莓派5安装ROS1避坑指南:从系统配置到cmake报错全解决 本文详细介绍了在树莓派5上安装ROS1的完整流程,包括系统配置、环境变量设置、cmake报错解决等关键步骤。针对树莓派5的ARM架构特性,提供了从基础安装到高级调试的系统级解决方案,帮助开发者高效部署ROS1并避免常见编译陷阱。特别针对cmake报错问题,给出了深度解析和实用修复方法。 阅读详情

传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1975

思路:可以用A*做,但是要手写堆或者用pb_ds的堆,不然会被卡空间

(原题256M,bzoj64M...)

设出发点为S,结束点为T,边权为val(e),边的出发点为head(e),到达点为tai(e)

也可以用论文方法,参见俞鼎力的《堆的可持久化和k短路》论文

首先我们建出最短路树,如果有多条任取一条以保证其树形结构

那么这棵树就是一个以结束点T为根的树

对于图中每条边e,定义它的偏离值delta(e)=val(e)+dis(tail(e),T)-dis(head(e),T)

表示换成这条边后,路径长度会增加多少


我们定义一条路径p中不在最短路径树中的边按从S到T的顺序构成的序列为s(p)

那么路径p的长度就是最短路长+p中所有边的偏离值

并且该序列中相邻两条边e,f满足head(f)是tail(e)在最短路径树上的祖先(包括自己)

这个性质很显然,相邻两条边之间只会有树边或者没有其他边,树边又总是从儿子指向父亲


然后我们要证明,满足该条件的序列和一条路径是一一对应的

这个也比较显然,两点间的树上路径当然只有一条


现在的问题就是求权值第k小这种序列

用一个优先队列维护,每个节点记录两个值,路径长度和结束点,

初始加入一个空序列,表示最短路

我们对每个点建立一个堆,存储所有以该点及该点祖先出发的边,因为序列要满足上面的性质

怎样得到一个新序列呢

我们可以把当前边替换成堆中的次大边,也可以新加入一条该边结束点的堆中的边以得到一个新序列


观察发现,复杂度在建立每个点的堆上

但我们并不需要这么做

树上儿子节点的堆只是在树上父亲节点的堆的基础上多加了一些边而已

所以写个可持久化的堆就可以了


(卡空间真是丧心病狂....,动态调整了一发可持久化堆的大小才卡过...)

upd:可持久化堆大小可以缩到maxm的4.5倍,空间只有30M左右,妈妈再也不用担心我被卡空间了..

#include<cmath>
#include<queue>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define PI pair<double,int>
#define mp(a,b) make_pair(a,b)
#define fi first
#define se second
#define pb(a) push_back(a)
const int maxn=5010,maxm=200010;
const double eps=1e-8;
using namespace std;
int n,m,pre[maxm],now[maxn],son[maxm],tot,fa[maxn],root[maxn],ans=1;double maxv,val[maxm],dis[maxn],mind;bool vis[maxn];
struct Edge{int x,y;double v,dta;}E[maxm];
priority_queue<PI,vector<PI>,greater<PI> > q;//用来记录所有序列的堆,first是偏离值之和,second是结束节点
void add(int a,int b,double c){pre[++tot]=now[a],now[a]=tot,son[tot]=b,val[tot]=c;}
bool is0(double a){return fabs(a)<eps;}
vector<int> s[maxn];
struct node{int ch[2],dis,ed;double val;}t[(int)(maxm*9)];

void read(int &x){
	char ch;
	for (ch=getchar();!isdigit(ch);ch=getchar());
	for (x=0;isdigit(ch);ch=getchar()) x=x*10+ch-'0';
}

struct Tltree{
	#define ls t[p].ch[0]
	#define rs t[p].ch[1]
	int tot;
	int newnode(int son,double v){
		t[++tot]=(node){0,0,0,son,v};
		return tot;
	}
	int merge(int x,int y){
		if (!x||!y) return x+y;
		if (t[x].val>t[y].val) swap(x,y);
		int p=++tot;
		t[p]=t[x],rs=merge(y,t[x].ch[1]);
		if (t[ls].dis<t[rs].dis) swap(ls,rs);
		t[p].dis=t[rs].dis+1;
		return p;//返回p,不是tot!!!
	}
}h;//用来存储从每个点自己及祖先出发的边的堆

struct Toppgraph{//预处理出每个点到n的距离
	int pre[maxm],now[maxn],son[maxm],tot;double val[maxm];
	void add(int a,int b,double c){pre[++tot]=now[a],now[a]=tot,son[tot]=b,val[tot]=c;}
	void prework(){
		memset(dis,127,sizeof(dis));
		dis[n]=0,q.push(mp(0,n));
		while (!q.empty()){
			int x=q.top().se;double d=q.top().fi;q.pop();
			for (int y=now[x];y;y=pre[y])
				if (dis[son[y]]>d+val[y]+eps)
					dis[son[y]]=d+val[y],q.push(mp(dis[son[y]],son[y]));
		}
		while (!q.empty()) q.pop();
		mind=dis[1];
	}
}opp;

void dfs(int x){
	bool find=0;
	if (x!=n){
		for (int y=now[x];y;y=pre[y]){
			double delta=dis[son[y]]+val[y]-dis[x];
			if (son[y]==fa[x]&&is0(delta)&&!find) find=1;//如果有权值相同的,都在最短路径树上的边,任取一条即可
			else root[x]=h.merge(root[x],h.newnode(son[y],delta));//否则扔进该点的堆里
		}
	}
	for (int y=opp.now[x];y;y=opp.pre[y]){//从T开始 反着往回建树边
		int v=opp.son[y];
		if (!fa[v]&&is0(dis[x]+opp.val[y]-dis[v]))//如果还没确定是哪条,且该边可能在最短路上,就把它当作树边
			fa[v]=x,root[v]=root[x],dfs(v);
	}
}

int main(){
	//freopen("magic1.in","r",stdin),freopen("magic.out","w",stdout);
	int x,y;double z;t[0].dis=-1;
	scanf("%d%d%lf",&n,&m,&maxv);
	for (int i=1;i<=m;i++) read(x),read(y),scanf("%lf",&z),add(x,y,z),opp.add(y,x,z);
	opp.prework(),root[n]=0,fa[n]=n,dfs(n);
	//for (int i=1;i<=n;i++) printf("i=%d fa=%d %.1lf\n",i,fa[i],dis[i]);
	//for (int i=1;i<=n;i++) printf("i=%d root=%d\n",i,root[i]);
	if (!root[1]) return printf("%d\n",ans),0;
	memset(vis,0,sizeof(vis)),vis[n]=1;
	
	q.push(mp(t[root[1]].val,root[1]));
	maxv-=dis[1];
	while (!q.empty()&&dis[1]+q.top().fi<=maxv){
		maxv-=dis[1]+q.top().fi;
		PI now=q.top();
		//printf("top=%.1lf\n",q.top().fi);
		q.pop(),ans++;
		for (int i=0;i<2;i++){//可以换成次大的以得到k+1短
			int next=t[now.se].ch[i];
			if (next) q.push(mp(now.fi-t[now.se].val+t[next].val,next));
		}
		int ed=t[now.se].ed;
		if (root[ed]) q.push(mp(now.fi+t[root[ed]].val,root[ed]));//也可以多加一条合法的不在最短路径树中的边得到k+1短
	}
	printf("%d\n",ans);
	return 0;
}

/*
4 6 14.9
1 2 1.5
2 1 1.5
1 3 3
2 3 1.5
3 4 1.5
1 4 1.5
*/



【ORB_SLAM系列4】—— 一文搞定如何在Ubuntu20.04中安装运行ORB_SLAM3(包含ROS版本和非ROS版本) ORB-SLAM3是一款基于特征点的实时单目SLAM系统,是SLAM领域的研究热点之一。它的核心算法是结合了ORB特征点提取和描述子匹配、单目RGB相机的深度估计、运动估计和地图优化等步骤,能够在实时性和精度之间取得平衡,适用于各种环境下的定位和建图任务。在各种应用领域都有广泛的应用。本教程主要是介绍了关于在ubuntu20.04中运行ORB_SLAM3的所有依赖的库的安装过程,和所遇到的一些报错的解决方法。有什么问题,可以评论区里面交流讨论 阅读详情

相关推荐

SAP物料主数据表结构全解析:ABAP开发与MM模块必知必会

本文深入解析SAP物料主数据的核心表结构,涵盖MARA、MAKT、MARC、MARD及MVKE等关键表。详细阐述了物料主数据在ABAP开发和MM模块中的存储逻辑与关联关系,帮助开发者和顾问高效处理数据查询、增强功能及业务故障排查,是掌握SAP物料管理基础的必读指南。

weixin_29216957的博客 379

BZOJ1975[Sdoi2010]魔法猪学院——可持久化可并堆+最短路树

题目描述 iPig在假期来到了传说中的魔法猪学院,开始为期两个月的魔法猪训练。经过了一周理论知识和一周基本魔法的学习之后,iPig对猪世界的世界本原有了很多的了解:众所周知,世界是由元素构成的;元素与元素之间可以互相转换;能量守恒……。 能量守恒……iPig 今天就在进行一个麻烦的测验。iPig 在之前的学习中已经知道了很多种元素,并学会了可以转化这些元素的魔法,每种魔法需要消耗 iPig 一定...

weixin_34191845的博客 194

用Python+NumPy手把手实现分数阶傅里叶变换(FRFT),搞定线性调频信号分析

本文详细介绍了如何使用Python和NumPy实现分数阶傅里叶变换(FRFT),特别针对线性调频信号(Chirp信号)分析。通过从零开始的代码实现和可视化案例,展示了FRFT在时变信号处理中的强大能力,帮助工程师和研究人员高效分析频率随时间变化的信号。

weixin_29062823的博客 218

BZOJ 1975: [Sdoi2010]魔法猪学院

二次联通门 :BZOJ 1975: [Sdoi2010]魔法猪学院 /* BZOJ 1975: [Sdoi2010]魔法猪学院 k短路 统计一下在能量用完之前走了多少条到终点的路即可 */ #include <cstdio> #include <queue> #include <iostream...

weixin_30544657的博客 151

AI使用指南:6个超实用的Prompt提示词模板

最近越来越多人开始接触AI,但其实想要让AI更懂你,关键是掌握对的提示词模板!今天就给大家分享6种超实用的Prompt提示词模板,不管你是小白还是老手都能用

程序员世杰 8170

FactoryTool量产神器实战:5分钟搞定多块RK3568板卡并行烧录

本文详细介绍了使用瑞芯微FactoryTool对多块RK3568板卡进行高效并行烧录的实战指南。文章从硬件连接、驱动配置、软件操作到排错技巧,提供了一套完整的量产解决方案,重点阐述了如何利用该工具在5分钟内完成多设备固件烧录,并确保eMMC存储的写入稳定性与效率,大幅提升生产线吞吐量。

b0c1d2的博客 987

【SDOI 2010】魔法猪学院

算法标签:A*

forever_dreams的博客 573

【图像去噪】基于加权核范数最小化算法实现图像去噪附matlab代码

1 简介 WNNM是一种约束矩阵奇异值稀疏性的低秩算法,在NNM理论基础上增加了核范数权重,有效利用了自然图像的先验信息并提高了核范数的灵活性. 2 部分代码 ​clcclear allclose allnSig = 100;O_Img = double(imread('Monarch.png'));​randn('seed', 0);N_Img = O_Img + nSig* randn(size(O_Img)); ..

qq_59747472的博客 3114

【BZOJ】1975: [Sdoi2010]魔法猪学院

题意 \(n(2 \le n \le 5000)\)个点,找尽量多的不同\(1\)到\(n\)的路径,每一次的花费就是路径的全值和,要求在费用不超过\(E\)的情况下路径最多。 分析 裸的最段路。 题解 A*算法即可。 #include <bits/stdc++.h> using namespace std; typedef double lf; const int N=50...

128

Win11右下角不显示图标怎么办?Win11右下角不显示图标的解决方法

所以有不少符合资格的小伙伴都下载进行体验了,但是有的小伙伴在升级完系统之后发现桌面右下角不显示任何图标,那么遇到这种情况要怎么办呢?下面就和小编一起来看看有什么解决方法吧。2、接着找到任务栏设置中的“taskbar corner overflow”。3、然后在下方勾选打开想要显示的图标程序就可以了。1、首先右键任务栏,在其中选择“任务栏设置”。目前微软已经正式推出了。

2401_88800025的博客 884

vue-vben-admin 打包编译报错Failed to resolve entry for package “@vben-core/design“ 的解决方法

如果你在你是不是在 apps/子目录下执行了 build?# 项目根目录 pnpm build而不是在下面单独打包。这个问题本身不复杂,但非常容易被误导去“怀疑依赖、怀疑配置、怀疑人生”。实际上,只要理解vue-vben-admin 是 monorepo 架构,很多类似问题都会迎刃而解。如果你后面还遇到 vben-admin 的构建、部署、权限或性能相关问题,这一套思路都很有用。希望这篇记录,能帮你节省至少半小时的排坑时间。

代码简单说 Vue、JAVA、PHP、Node.js 熟练运用,接口、架构、性能全搞定。 423

BZOJ 1975: [Sdoi2010]魔法猪学院【K短路,A*

就用dijkspfa这种玄学东西啊…… 看题显然就是从最短路开始从小往大选择,于是就是求前k短路 考虑对于一个节点i,维护dis[i]表示从i到n的最短路长度,d1[i]表示从1到i当前走过的路径长度,用priority_queue维护这两个的和,每次取最小的显然最优 …………谁说priority_queue要卡空间啊……明明没卡嘛QAQ,辣鸡flaze xjb写了个配对堆MLE了一年233

Flaze_的博客 606

HTML5+CSS3+JS小实例:焦点图波浪切换动画特效

实例:焦点图波浪切换动画特效。字体图标库:Font Awesome。技术栈:HTML+CSS+JS。

艾恩小灰灰的博客 907

bzoj 1975: [Sdoi2010]魔法猪学院 (k短路)

1975: [Sdoi2010]魔法猪学院 Time Limit: 10 Sec  Memory Limit: 64 MB Submit: 1959  Solved: 601 [Submit][Status][Discuss] Description iPig在假期来到了传说中的魔法猪学院,开始为期两个月的魔法猪训练。经过了一周理论知识和一周基本魔法的学习之后,iPig对猪世界的世界

clover_hxy的博客 451

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

BZOJ1975: [Sdoi2010]魔法猪学院

第一道A*。。。 今天才会做k短路。。。。 #include #include #include #include #include using namespace std; struct Node { int x; double dis; inline friend bool operatorb.dis; } }; struct node { double f,g; int

Don't fake it till you made it 639

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

bzoj 1975: [Sdoi2010]魔法猪学院 [k短路]

1975: [Sdoi2010]魔法猪学院 裸题... 被double坑死了 #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <queue> using namespace std; typedef long lo...

weixin_30670965的博客 71

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

BZOJ 1975: [Sdoi2010]魔法猪学院 K短路 dijkstra A*

1975: [Sdoi2010]魔法猪学院 Time Limit: 10 Sec  Memory Limit: 64 MB Submit: 2235  Solved: 696 [Submit][Status][Discuss] Description iPig在假期来到了传说中的魔法猪学院,开始为期两个月的魔法猪训练。经过了一周理论知识和一周基本魔法的学习之后,iPig对猪世界的世界

BlackJack 450

BZOJ1975: [Sdoi2010]魔法猪学院(A*)

传送门题意: 求k短路。题解: 标准A*,先从终点SPFA,保证估价函数的正确。(感觉这个复杂度很不科学。。)#include<bits/stdc++.h> #include<ext/pb_ds/priority_queue.hpp> using namespace std; using namespace __gnu_pbds; typedef pair<int,double> pid; co

DZYO的博客 780

bzoj 1975: [Sdoi2010]魔法猪学院 k短路+A*

题意给出n个点m条有向边,求最多有多少条1到n的不同路径使得每条路劲的权值加起来不超过c。 n<=5000,m<=200000分析很显然题目是要我们找一个最大的k满足1到n前k短的路径和不超过c。 那么我们就要来求k短路。k短路用spfa来实现,每次在优先队列里面取一个估价函数f(i)=g(i)+h(i)的点出来去更新其他的点,若一个点第k次出队则这次必然是第k短路。g(i)表示的是1到i当前的

beginend 486

BZOJ 1975: [Sdoi2010]魔法猪学院——K短路,A*

传送门 http://www.lydsy.com/JudgeOnline/problem.php?id=1975 题意&简要做法 一张有向图,求出最多的互不相同的路径,满足路径长度之和\(\leq E\)。 可以转化为求K短路。注意这里不需要二分,只要不断取得剩下的路径里的最短路,累加权值直到超过E即可。 细节 原题&洛谷上有256M空间,BZOJ上只有64M,坑啊... 加入一些...

weixin_30832405的博客 125

【模板】BZOJ1975: [Sdoi2010]魔法猪学院-A*算法-k短路

传送门:bzoj1975 题解 启发式搜索中的估价函数/A*算法 先跑一遍节点n的最短路 此题中用小根堆维护(fi,i)(fi,i)(f_i,i) fi=gi+hifi=gi+hif_i=g_i+h_i 这里的hihih_i就是当前点到目标节点n的最短路距离。gigig_i是起点到当前点的目前状态所走过的路径长度。 代码 #include&amp;lt;cstdio&amp;gt; ...

远行客 312

BZOJ 1975: [Sdoi2010]魔法猪学院 大水题 第k短路 spfa

https://www.lydsy.com/JudgeOnline/problem.php?id=1975 我好像到现在了第k短路都不会写,mdzz。 先spfa求出最短路,然后扫点存各种前置路径已经决定的最短路,小根堆暴力即可。 有向图要存反向边,写完才发现的,临时添成两种了,丑也没办法 1 #include<iostream> 2 #include<cs...

weixin_30363509的博客 84

【k短路&A*算法】BZOJ1975: [Sdoi2010]魔法猪学院

Description 找出1~k短路的长度。 Solution k短路的求解要用到A*算法 A*算法的启发式函数f(n)=g(n)+h(n) g(n)是状态空间中搜索到n所花的实际代价 h(n)是n到结束状态最佳路径的估计代价 关于h(n)的选取,当h(n)<实际代价时,搜索慢但可出解;h(n)=实际代价时,正确率与效率最高;h(n)>实际代价,快但只能得到近...

weixin_30790841的博客 140
上一篇: bzoj1598: [Usaco2008 Mar]牛跑步
下一篇: APIO2015&2014题解
thy_asdf
博客等级 码龄12年 16粉丝 186原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值