[BZOJ1726][Usaco2006 Nov]Roadblocks第二短路

本文介绍了一道经典的图论题目——寻找两点间的第二短路径问题。该问题通过改进的迪杰斯特拉算法解决,实现允许重复经过同一条边并找到次短路径的目标。

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

1726: [Usaco2006 Nov]Roadblocks第二短路

Time Limit: 5 Sec  Memory Limit: 64 MB Submit: 1277  Solved: 607 [Submit][Status][Discuss]

Description

贝茜把家搬到了一个小农场,但她常常回到FJ的农场去拜访她的朋友。贝茜很喜欢路边的风景,不想那么快地结束她的旅途,于是她每次回农场,都会选择第二短的路径,而不象我们所习惯的那样,选择最短路。 贝茜所在的乡村有R(1<=R<=100,000)条双向道路,每条路都联结了所有的N(1<=N<=5000)个农场中的某两个。贝茜居住在农场1,她的朋友们居住在农场N(即贝茜每次旅行的目的地)。 贝茜选择的第二短的路径中,可以包含任何一条在最短路中出现的道路,并且,一条路可以重复走多次。当然咯,第二短路的长度必须严格大于最短路(可能有多条)的长度,但它的长度必须不大于所有除最短路外的路径的长度。

Input

* 第1行: 两个整数,N和R,用空格隔开

* 第2..R+1行: 每行包含三个用空格隔开的整数A、B和D,表示存在一条长度为 D(1 <= D <= 5000)的路连接农场A和农场B

Output

* 第1行: 输出一个整数,即从农场1到农场N的第二短路的长度

Sample Input

4 4
1 2 100
2 4 200
2 3 250
3 4 100


Sample Output

450

输出说明:

    最短路:1 -> 2 -> 4 (长度为100+200=300)
    第二短路:1 -> 2 -> 3 -> 4 (长度为100+250+100=450)
 
次短路模板题
#include <queue>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
char buf[10000000], *ptr = buf - 1;
inline int readint(){
    int n = 0;
    char ch = *++ptr;
    while(ch < '0' || ch > '9') ch = *++ptr;
    while(ch <= '9' && ch >= '0'){
        n = (n << 1) + (n << 3) + ch - '0';
        ch = *++ptr;
    }
    return n;
}
const int maxn = 5000 + 10, maxm = 100000 + 10;
struct Edge{
    int to, val, next;
    Edge(){}
    Edge(int _t, int _v, int _n): to(_t), val(_v), next(_n){}
}e[maxm * 2]; 
int fir[maxn] = {0}, cnt = 0;
inline void ins(int u, int v, int w){
    e[++cnt] = Edge(v, w, fir[u]); fir[u] = cnt;
    e[++cnt] = Edge(u, w, fir[v]); fir[v] = cnt;
}

struct Node{
    int dis, idx;
    Node(){}
    Node(int _d, int _i): dis(_d), idx(_i){}
    bool operator < (const Node &x) const {
        return dis > x.dis;
    }
}t;
priority_queue<Node> q;
int dis1[maxn], dis2[maxn];
void dijkstra(){
    memset(dis1, 0x3f, sizeof dis1);
    memset(dis2, 0x3f, sizeof dis2);
    dis1[1] = 0;
    q.push(Node(0, 1));
    int u, v, w;
    while(!q.empty()){
        t = q.top(); q.pop();
        u = t.idx;
        if(t.dis > dis2[u]) continue;
        for(int i = fir[u]; i; i = e[i].next){
            v = e[i].to;
            w = t.dis + e[i].val;
            if(dis1[v] > w){
                swap(dis1[v], w);
                q.push(Node(dis1[v], v));
            }
            if(dis1[v] < w && w < dis2[v]){
                dis2[v] = w;
                q.push(Node(dis2[v], v));
            }
        }
    }
}
int n, m;
int main(){
    fread(buf, sizeof(char), sizeof(buf), stdin); 
    n = readint();
    m = readint();
    for(int u, v, w, i = 1; i <= m; i++){
        u = readint();
        v = readint();
        w = readint();
        ins(u, v, w);
    }
    dijkstra();
    printf("%d\n", dis2[n]);
    return 0;
}

 

转载于:https://www.cnblogs.com/ruoruoruo/p/7486995.html

基于Spring Boot搭建的一个多功能在线学习系统的实现细节。系统分为管理员和用户两个主要模块。管理员负责视频、文件和文章资料的管理以及系统运营维护;用户则可以进行视频播放、资料下载、参与学习论坛并享受个性化学习服务。文中重点探讨了文件下载的安全性和性能优化(如使用Resource对象避免内存溢出),积分排行榜的高效实现(采用Redis Sorted Set结构),敏感词过滤机制(利用DFA算法构建内存过滤树)以及视频播放的浏览器兼容性解决方案(通过FFmpeg调整MOOV原子位置)。此外,还提到了权限管理方面自定义动态加载器的应用,提高了系统的灵活性和易用性。 适合人群:对Spring Boot有一定了解,希望深入理解其实际应用的技术人员,尤其是从事在线教育平台开发的相关从业者。 使用场景及目标:适用于需要快速搭建稳定高效的在线学习平台的企业或团队。目标在于提供一套完整的解决方案,涵盖从资源管理到用户体验优化等多个方面,帮助开发者更好地理解和掌握Spring Boot框架的实际运用技巧。 其他说明:文中不仅提供了具体的代码示例和技术思路,还分享了许多实践经验教训,对于提高项目质量有着重要的指导意义。同时强调了安全性、性能优化等方面的重要性,确保系统能够应对大规模用户的并发访问需求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值