CCF201503-5 最小花费 一种思路

 

这道题看到网上的题解基本都用dfs,但是可能会超时。所以我想可以先用欧拉序和rmq处理一下,然后对于每一次询问求出起点终点的lca,再把整个路径分为从起点到lca,lca到终点两部分处理。  

我用的python,最后只得了10分。。。说是运行错误。这个方法我觉得还是对的,自己弄了个比较麻烦的样例也对了。

然后把我当时做完后做的小结贴出来:

这道题想法应该是对的,因为是最短路不变,且用n-1条路就把n个点都连通,所以是个树的形状。刚开始就用graph存着这个双向路,
存完以后,人为把1作为树的树根,从1开始dfs,每到一个点就把该点标记为已访问(用visited实现),然后对于其未访问的子节点,
把它加进改点儿子列表中(zheng_graph),并且存起ni_graph[son][father] = length,然后dfs这个儿子节点。因为树,每个父亲节
点可以有多个儿子节点,但是一个儿子节点只有一个父亲节点,所以存一个ni_graph。一个树状的结构就建好啦。处理以后用欧拉序 rmq
可以求每两个点的lca,然后对于询问每一对起点和终点,求出它们的lca,然后从起点开始,从下到上直接到lca,在这期间,从起点到
起点的父亲节点这一小段路,只能在起点买食物。对于以后的路径,一段一段的分析,每一段都用之前经过的所有点的最便宜价格食物乘这
段路长。到了lca以后就要分析lca到终点这一段路,因为ni_graph只储存了终点到lca的路径长度,所以设一个zan,从终点到lca遍历,
交换父亲节点和儿子节点,这样就把这一段路变成了和起点到lca那一段路一样的处理方法,同样也是一小段一小段的处理,每一小段都
用最便宜的食物。

初学者有很多东西可能都说错了,见谅了。

 

 

 

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值