洛谷P2832 行路难 分析+题解代码【玄学最短路】


题目背景:

小X来到了山区,领略山林之乐。在他乐以忘忧之时,他突然发现,开学迫在眉睫

题目描述:

山区有n座山。山之间有m条羊肠小道,每条连接两座山,只能单向通过,并会耗费小X一定时间。

小X现在在1号山,他的目的是n号山,因为那里有火车站。

然而小X的体力是有限的。他每通过一条羊肠小道,就会变得更疲劳,导致他通过任意一条羊肠小道的时间都增加1。

输入格式:

第一行两个数,n,m

第2行到第m+1行,每行3个数A,B,C,表示A、B之间有一条羊肠小道,可以让小X花费C的时间从A移动到B

输出格式:

两行 第一行一个数T,表示小X需要的最短时间

第二行若干个数,用空格隔开,表示小X的移动路线

例:1 4 2 5表示:小X从1号山开始,移动到4号山,再到2号山,最后到5号山。

输入样例:

5 8

2 4 2

5 2 1

1 2 1

4 3 2

1 3 3

4 5 2

1 5 8

3 5 3

输出样例:

5 8

2 4 2

5 2 1

1 2 1

4 3 2

1 3 3

4 5 2

1 5 8

3 5 3


算法分析:

很明显这是一道最短路(这不是废话嘛)

不过这道题引入了一个疲劳度

乍一看似乎挺难

但其实只要在更新最短路的时候

记录当前被更新最短路的节点i之前已经走过了几节点

即我们以num[v]表示v之前已经走过了几个节点

num[v]=num[u]+1;

u为能使到达v的最短路更新的上一个中介点

所以我们只要在下一次以v为中介点判断是否能更新最短路时加上num[v]即可

其余就只剩SPFA的模板了


废话不多说,呈上蒟蒻代码

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<queue>
#include<cstring>
using namespace std;

int n,m;
struct node
{
    int v;
    int dis;
};
vector<node> map[1000010];
int d[1000010];
int num[1000010];//记录疲劳值的数组,初始全部为0
bool inq [1000010];
int pre[1000010];//记录最短路径

void print(int u)
{
    if(pre[u]==u)
    {
        cout<<u<<" ";
        return ;
    }

    print(pre[u]);
    cout<<u<<" ";
}

void SPFA()
{
    for(int i=1;i<=n;i++)
    pre[i]=i;
    memset(d,127,sizeof(d));
    queue<int> q;
    q.push(1);
    inq[1]=true;
    d[1]=0;

    while(!q.empty())
    {
        int u=q.front();
        inq[u]=false;
        q.pop();

        for(int j=0;j<map[u].size();j++)
        {
            int v=map[u][j].v;
            int dis=map[u][j].dis;

            if(d[u]+dis+num[u]<d[v])
            {
                d[v]=d[u]+dis+num[u];
                pre[v]=u;
                num[v]=num[u]+1;//**高亮**这里更新num[v]的疲劳值
                if(!inq[v])
                {
                    q.push(v);
                    inq[v]=true;
                }
            }
        }
    }
}

int main()
{
    cin>>n>>m;
    for(int i=1;i<=m;i++)
    {
        int s,t,dis;
        cin>>s>>t>>dis;
        map[s].push_back( (node) {t,dis});
    }

    SPFA();
    cout<<d[n]<<endl;
    print(n);
    return 0;
} 

其实就是在SPFA模板里多加了一行。。。

妥妥的 “提高+/省选-” 玄学最短路

洛谷P2832 行路难 分析+题解代码【玄学最短路】的更多相关文章

  1. 洛谷 P2832 行路难

    题面 这个最短路有点special,会有疲劳度的加成效应,这个时候应该怎么办呢? 难就难在,如果走一条路比另一条路长,但是用的边少,那么这条路并不一定就更差. 我们要是能解决这个问题,就可以做出本题. ...

  2. 洛谷P1345 [USACO5.4]奶牛的电信Telecowmunication【最小割】分析+题解代码

    洛谷P1345 [USACO5.4]奶牛的电信Telecowmunication[最小割]分析+题解代码 题目描述 农夫约翰的奶牛们喜欢通过电邮保持联系,于是她们建立了一个奶牛电脑网络,以便互相交流. ...

  3. 洛谷 P2194 HXY烧情侣【Tarjan缩点】 分析+题解代码

    洛谷 P2194 HXY烧情侣[Tarjan缩点] 分析+题解代码 题目描述: 众所周知,HXY已经加入了FFF团.现在她要开始喜(sang)闻(xin)乐(bing)见(kuang)地烧情侣了.这里 ...

  4. 洛谷P1783 海滩防御 分析+题解代码

    洛谷P1783 海滩防御 分析+题解代码 题目描述: WLP同学最近迷上了一款网络联机对战游戏(终于知道为毛JOHNKRAM每天刷洛谷效率那么低了),但是他却为了这个游戏很苦恼,因为他在海边的造船厂和 ...

  5. 洛谷P1854 花店橱窗布置 分析+题解代码

    洛谷P1854 花店橱窗布置 分析+题解代码 蒟蒻的第一道提高+/省选-,纪念一下. 题目描述: 某花店现有F束花,每一束花的品种都不一样,同时至少有同样数量的花瓶,被按顺序摆成一行,花瓶的位置是固定 ...

  6. 【洛谷P3960】列队题解

    [洛谷P3960]列队题解 题目链接 题意: Sylvia 是一个热爱学习的女孩子. 前段时间,Sylvia 参加了学校的军训.众所周知,军训的时候需要站方阵. Sylvia 所在的方阵中有 n×m ...

  7. 洛谷P1577 切绳子题解

    洛谷P1577 切绳子题解 题目描述 有N条绳子,它们的长度分别为Li.如果从它们中切割出K条长度相同的 绳子,这K条绳子每条最长能有多长?答案保留到小数点后2位(直接舍掉2为后的小数). 输入输出格 ...

  8. 洛谷P2507 [SCOI2008]配对 题解(dp+贪心)

    洛谷P2507 [SCOI2008]配对 题解(dp+贪心) 标签:题解 阅读体验:https://zybuluo.com/Junlier/note/1299251 链接题目地址:洛谷P2507 [S ...

  9. 洛谷P2312 解方程题解

    洛谷P2312 解方程题解 题目描述 已知多项式方程: \[a_0+a_1x+a_2x^2+\cdots+a_nx^n=0\] 求这个方程在 \([1,m]\) 内的整数解(\(n\) 和 \(m\) ...

随机推荐

  1. 急!!ftp登录错误,提示 530 not logged in,连接失败 ,,是怎么回事啊

    愤怒地青鸟 | 浏览 68533 次 发布于2017-04-11 00:44 最佳答案 核心提示:Ftp登陆不了是很经常碰到的事,很多人常常是不加分析就发贴询问.老实说,这样既浪费自己时间,又浪费别人 ...

  2. ngRx 官方示例分析 - 3. reducers

    上一篇:ngRx 官方示例分析 - 2. Action 管理 这里我们讨论 reducer. 如果你注意的话,会看到在不同的 Action 定义文件中,导出的 Action 类型名称都是 Action ...

  3. [SinGuLaRiTy] 复习模板-高精度模板

    [SinGuLaRiTy-1042] Copyright (c) SinGuLaRiTy 2017. All Rights Reserved. 结构体封装 //高精度运算 注意%I64d与%lld # ...

  4. [SinGuLaRiTy] 复习模板-图论

    [SinGuLaRiTy-1041] Copyright (c) SinGuLaRiTy 2017. All Rights Reserved. 计算树的直径 //方法:任选一个点作为起点进行一次BFS ...

  5. ios VS android

    本来是学习IOS的,但是最近接到的是有关于安卓的项目,害怕弄混,所以在这个技术博客里写一下对比. IOS                                                 ...

  6. linux如何自动获取ip地址

    第一步:激活网卡 系统装好后默认的网卡是eth0,用下面的命令将这块网卡激活. # ifconfig eth0 up 第二步:设置网卡进入系统时启动 想要每次开机就可以自动获取IP地址上网,就要设置网 ...

  7. Python 字符串大小写操作

    #coding=utf-8 #python中字符串的操作 # 字符串的大小写 s='hello_wOrld_oF_you' upper_str = s.upper() print('全部大写: ',u ...

  8. Tomcat常用操作

    Tomcat简介 TOMCAT是APACHE JAKARTA软件组织的一个子项目,TOMCAT是一个JSP/SERVLET容器,它是在SUN公司的JSWDK(JAVA SERVER WEB DEVEL ...

  9. 壮美大山包-2017中国大山包国际超百公里ITRA积分赛赛记

    2017年4月份用时28个多小时跑完江南100,付出的代价是双脚多达8个以上的水泡.所以接下来的4月29日的环汶川越野赛果断的从60公里换到了30公里组,慢悠悠的完成了. 虽然在赛道上一度想再也不参加 ...

  10. android在一个应用程序员启动另一个程序

    一般我们知道了另一个应用的包名和MainActivity的名字之后便可以直接通过如下代码来启动: Intent intent = new Intent(Intent.ACTION_MAIN); int ...