BZOJ1576 USACO 2009 Jan Gold 3.Safe Travel Solution

该博客介绍了USACO 2009年1月竞赛的Gold 3题目Safe Travel Solution的解决方案。博主首先通过单源最短路算法构建最短路径树,然后讨论了如何处理删除特定边后求解新的最短路径的方法。关键在于理解,当删除特定边后,必须通过非树边才能到达目标节点,且最优路径仅包含一条非树边。博主使用树链剖分来维护这些信息,并以O(mlogn)的时间复杂度完成算法,但注意到常数优化非常重要,最终采用SLF-spfa算法解决了这个问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题意:一个无向图,保证点1到其余点的最短路径存在且唯一。现在对于点2~n,询问若删去点1到这个点最短路上的最后一条边,此时点1到这个点新的最短路长度是多少。若不存在路径输出-1.


Solution:

首先跑一遍源点为1的单源最短路,随后建立以1为根的最短路径树。在最短路径树中,一个点的父亲节点是1到这个点的最短路上的倒数第二个点。

那么对于每个询问,事实上是断掉树上这个点和其父亲之间的边,求解新的最短路。

此时1和这个点不联通了,显然我们必须通过非树边才可能到达这个点。

显然能够证明若存在一条路径,那么当其最短时经过的非树边至多只有一条。

因此我们考虑每一条非树边对某些点答案的影响。

设一条非树边(x,y),若x不在以z为根的子树中,且y在以z为根的子树中,那么若z与z的父亲之间的边断掉,我们可以通过边(x,y)来到达z.那么我们经过的路径长度呢?

不妨设点1到点i的最短路长度为dis[i],则路径长度为dis[x]+len(x,y)+dis[y]-dis[z].不妨设为g(x,y)-dis[z].

因此,对于每个点z,我们只需维护出min{g(x,y)}.最终将答案减去dis[z]即可。

那么对于一条边(x,y)它能更新哪些点呢?

通过画图我们发现,它能更新路径(x,y)除了lca(x,y)之外的所有点。

那么利用树链剖分维护即可。

总的时间复杂度为O(mlogn).

虽然最短路不是瓶颈,但却很卡常数。用了SLF-spfa才勉强卡过去。


Code:

//SLF-Spfa
#include <cstdio>
#include <cstring>
#include <cctype>
#include <iostream>
#include <algorithm>
#include <queue>
using namespace std;
 
inline int getc() {
    static const int L = 1 << 15;
    static char buf[L], *S = buf, *T = buf;
    if (S == T) {
        T = (S = buf) + fread(buf, 1, L, stdin);
        if (S == T)
            return EOF;
    }
    return *S++;
}
inline int getint() {
    int c;
    while(!isdigit(c = getc()));
    int tmp = c - '0';
    while(isdigit(c = getc()))
        tmp = (tmp << 1) + (tmp &l
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值